var DrawEnca = (function(){
    const isFirefox = navigator.userAgent.indexOf("Firefox") !== -1;

    let count = 0;

    // 事件处理器
    const Event = (function(){
        
        let _eventList = {};

        let namespace = "default";

        var event = {

            // 添加事件监听
            on(eventName,execute,alias){
                if(!_eventList[namespace]){
                    _eventList[namespace] = {};
                }
                if(!_eventList[namespace][eventName]){
                    _eventList[namespace][eventName] = [];
                }
                if(!alias){
                    alias = "default"
                }
                _eventList[namespace][eventName].push({
                    alias,
                    execute
                });
                // namespace = "default";
            },

            // 取消事件监听
            off(eventName,execute){
                if(!_eventList[namespace] || !_eventList[namespace][eventName]){
                    return;
                }
                for(let i = 0; i < _eventList[namespace][eventName].length; i++){
                    if(_eventList[namespace][eventName][i].execute == execute){
                        _eventList[namespace][eventName].splice(i--,1);
                        return true;
                    }
                }
                // namespace = "default";
            },

            // 通过别名取消事件
            aliasOff(eventName,alias){
                if(!_eventList[namespace] || !_eventList[namespace][eventName]){
                    return;
                }
                for(let i = 0; i < _eventList[namespace][eventName].length; i++){
                    if(_eventList[namespace][eventName][i].alias == alias){
                        _eventList[namespace][eventName].splice(i--,1);
                        return true;
                    }
                }
            },

            // 命名空间
            useSpace(name){
                return {
                    on(eventName,fun){
                        namespace = name;
                        event.on(eventName,fun);
                        namespace = "default";
                    },
                    off(eventName,fun){
                        namespace = name;
                        event.off(eventName,fun);
                        namespace = "default";
                    },
                    aliasOff(eventName,alias){
                        namespace = name;
                        event.aliasOff(eventName,alias);
                        namespace = "default";
                    },
                    trigger(eventName,...args){
                        namespace = name;
                        event.trigger(eventName,...args);
                        namespace = "default";
                    }
                };
            },

            // 触发事件
            trigger(eventName,...args){
                if(!_eventList[namespace] || !_eventList[namespace][eventName]){
                    return;
                }
                _eventList[namespace][eventName].forEach(event=>event.execute.apply(this,args));
            }
        }

        return event;
    })();

    // 画图策略
    const insertStrategy = {
        pin(options){
            let pinInfo = {
                pin_num: options.pins_id,
                padid: options.pads_id,
                pinid: options.pins_id
            }

            let config = {
                r:0,
                w:0,
                h:0,
                pinType:"via",
                num:options.num || 6,
                type:options.form,
                units:options.units,
                outOffset:{
                    x: 0,
                    y: 0
                },
                inOffset:{
                    x: 0,
                    y: 0
                },
                drillOption:{
                    w: 0,
                    h: 0,
                    r: 0
                }
            }

            let pinList = [];

            let padList = [];

            let pad = {};

            let pin = {};

            if(options.form == "SELF"){
                pad = util.copyObject(options.pad);
                pinInfo.padid = options.pad.id;
            }else{
                let r = config.units === "mm"?0.5*2:39.37*2;
                config.r = r;

                config.w = r;

                config.h = r;

                if(config.type === "OV"){
                    config.w *= 2/3;
                }

                config.w = config.w.toFixed(4)/1;

                config.h = config.h.toFixed(4)/1;

                config.drillOption = drillSize(config);

                pad = generateFigure.pad(config);

                config.drillOption

                pad.id = ++pinInfo.padid;
            }

            pinInfo.pin_num++;

            pinInfo.pinid++;

            pin = createPin(pinInfo,{x:0,y:0});

            pinList.push(pin);

            padList.push(pad);

            // 创建一个pin
            function createPin(pinConfig,point){
                let cpin = {
                    padid:pinConfig.padid,
                    pinid: pinConfig.pinid,
                    pin_num: pinConfig.pin_num,
                    x:point.x,
                    y:point.y,
                    rotate:0,
                    type:"pins"
                };
                return cpin;
            };

            // 处理需要编辑的数据
            function returnEditData(pin,config){
                var result = {
                    pin_num:pin.pin_num,
                    x:pin.x,
                    y:pin.y,
                    type:config.type.toUpperCase(),
                    rotate:pin.rotate,
                    r:config.r,
                    pinType:config.pinType,
                    outOffset:util.copyObject(config.outOffset),
                    inOffset:util.copyObject(config.inOffset),
                    drillOption:util.copyObject(config.drillOption)
                }
                var type = result.type;
                if(type === "C" || type === "OC" || type === "POLY"){
                    result.r = config.r;
                    if(type === "POLY"){
                        result.num = config.num;
                    }
                }
                if(type === "S" || type === "CS" || type === "OV"){
                    result.w = config.w;
                    result.h = config.h;
                }
                return result;
            }

            // 自适应过孔大小
            function drillSize(config){
                if(!config.r){
                    config.r = config.w>config.h?config.h:config.w;
                }
    
                if(config.type === "C"){
                    config.w = config.r;
                    config.h = config.r;
                }else{
                    config.w = config.w || config.r;
                    config.h = config.h || config.r;
                }
                
                let drillH = config.r/2,drillW = config.r/2,drillR = config.r/2;
                
                if(config.type === "OV"){
                    drillH = config.h*2/3;
                    drillW = config.w*2/3;
                    drillR = config.r/3;
                }
                if(config.pinType == "hole"){
                    return {
                        h:h,
                        w:w,
                        r:r/2
                    }
                }else{
                    return {
                        h:drillH,
                        w:drillW,
                        r:drillR
                    }
                }
                
                
            }

            // 生成编号
            function generateNumber(config){
                console.log(config)
                // let mode=obj.mode;
                let xnum = config.rowNumber;
                let ynum = config.colNumber;
                let txt  = config.startNum.toUpperCase();
                
                let ennum=textType(txt);
                let box=[];
                for(let i=0;i<xnum;i++){
                    let row=[];
                    let br=false;
                    if(i>0){
                        br=true;
                    }
                    for(let j=0;j<ynum;j++){

                        if(i==0 && j==0){
                            row.push(txt);
                        }else{
                            txt=textAdd(txt,ennum,br);
                            row.push(txt);
                            ennum=textType(txt);
                        }

                        
                        br=false;
                    }
                    box.push(row);
                }
                return box;

            };

            function textType(txt){
                let num=0;
                let test_en= new RegExp("^[A-Za-z]{"+num+"}\\d+$");
                for(let i=0;i<txt.length;i++){
                    if(!test_en.test(txt)){
                        num++;
                        test_en=new RegExp("^[A-Za-z]{"+num+"}\\d+$");
                    }
                }
                return num;
            };

            //自增
            function textAdd(txt,ennum,br){//文本，字母个数，换行
                let text_en=/^[a-zA-Z]+$/,         //字母检测
                    text_num=/^[0-9]*[1-9][0-9]*$/;//数字检测
                if(ennum==0){
                    return txt/1+1;
                }else{//字母
                    let en=txt.substr(0,ennum),
                        num=txt.substring(ennum);

                    if(text_en.test(en)&&text_num.test(num)){//字母加数字
                        if(br){
                            txt=en_add(en)+(1);
                        }else{
                            txt=en+(num/1+1);
                        }
                        
                    }else if(text_en.test(en)&&!text_num.test(num)){//纯字母
                        txt=en_add(en,br);
                        
                    }
                    return txt;
                }

                
                function en_add(entxt,br){//纯字母增
                    let length=entxt.length-1;
                    let en_end=entxt.substring(length);
                    let en_new="";
                    let en_head=entxt.substr(0,length);
                    let enAddlock=true;
                    let exclude =["I","O","Q","S","X","Z"]; //需要跳过的字母

                    if(en_end.toUpperCase()=="Y"||br){
                        let endnum=-1;
                        if(br){
                            length=length-1;//摒弃最后一位
                        }
                        for(let i=length;i>=0;i--){
                            en_end=entxt.substr(i,length-i+1);
                            if(en_end.toUpperCase()!="Y"){
                                endnum=i;
                                break;
                            }
                        }
                        if(endnum==-1){
                            en_end="Y"
                            endnum=0;
                        }

                        if(br){
                            if(entxt.length==1){
                                en_end=entxt;
                                endnum=0;
                                console.log(en_end)
                            }else{
                                for(let k=endnum;k<length+1;k++){
                                    en_new="A"+en_new;
                                }
                            }
                            
                        }else{
                            for(let k=endnum;k<length;k++){
                                en_new="A"+en_new;
                            }
                        }
                        
                        en_head=entxt.substr(0,endnum);
                        if(en_end.toUpperCase()=="Y"){
                            en_end="A";
                            if(en_head==""||en_head==null){
                                en_head="A";
                            }
                        }else{
                            en_end=String.fromCharCode(en_end.charCodeAt(0) + 1);
                            //检测是否是需要跳过的字母
                            exclude.forEach(value=>{
                                if(value==en_end){
                                    en_end = String.fromCharCode(en_end.charCodeAt(0) + 1);
                                }
                            });
                        }
                        entxt=en_head+en_end+en_new;
                        
                    }else{
                        en_end=String.fromCharCode(en_end.charCodeAt(0) + 1);
                        //检测是否是需要跳过的字母
                        exclude.forEach(value=>{
                            if(value==en_end){
                                en_end = String.fromCharCode(en_end.charCodeAt(0) + 1);
                            }
                        });
                        
                        entxt=en_head+en_end;
                    }
                    return entxt;
                }
            };

            // 生成列阵
            function generateArrays(config){
                console.log(config);
                // colNumber: 4
                // role: "row"
                // rowNumber: 4
                // show: true
                // startNum: 1
                // startX: 1
                // startY: 2
                // type: "arrays"
                // xSpacing: -3
                // ySpacing: -3
                let pinNumberList = generateNumber(config);
                console.log(pinNumberList)
                let pinList = [];

                let nowRow = config.ySpacing < 0 ? 0 : config.rowNumber - 1;

                for(let i = 0; i < config.rowNumber; i++){

                    let nowCol = config.xSpacing < 0 ? config.colNumber - 1 : 0;

                    for(let j = 0; j < config.colNumber; j++){
                        let pinConfig = {
                            padid:config.padid,
                            pinid: ++config.pinid,
                            pin_num:pinNumberList[i][j],
                        }
                        let point = {
                            x:config.startX + config.xSpacing * nowCol,
                            y:config.startY + config.ySpacing * nowRow
                        }
                        pinList.push(createPin(pinConfig,point));
                        config.xSpacing < 0 ? nowCol-- :  nowCol++;
                    }
                    config.ySpacing < 0 ? nowRow++ : nowRow--;
                }

                return {
                    pins:pinList,
                    pinid:config.pinid
                }
            }

            return {
                pin,

                pad,

                pinList,

                padList,

                config,

                pinInfo,

                createNewPin:false,

                clickEvent(point){
                    this.pin.x = point.x;
                    this.pin.y = point.y;

                    this.pinInfo.pin_num++;
                    this.pinInfo.pinid++;
                    this.pin = createPin(this.pinInfo,point);
                    this.pinList.push(this.pin);

                    return returnEditData(this.pin,this.config);
                },

                moveEvent(point){
                    if(this.createNewPin){
                        this.pinInfo.pin_num++;
                        this.pinInfo.pinid++;
                        this.pin = createPin(this.pinInfo,point);
                        this.pinList.push(this.pin);
                        this.createNewPin = false;
                    }

                    this.pin.x = point.x;
                    this.pin.y = point.y;

                    return returnEditData(this.pin,this.config);
                },

                edit(editData){
                    // 阵列放置
                    if(editData.type == "arrays"){
                        editData.pinid = pinInfo.pinid;
                        editData.padid = pinInfo.padid;
                        let pinsObj = generateArrays(editData);
                        this.pinList.splice(-1,0,pinsObj.pins);
                        this.pinInfo.pinid = ++pinsObj.pinid;
                        this.pin.pinid = ++pinInfo.pinid;
                        return;
                    }
                    if(this.pin.x !== editData.x || this.pin.y !== editData.y){
                        this.createNewPin = true;
                    }
                    this.pin.x = editData.x;
                    this.pin.y = editData.y;
                    this.pin.pin_num = editData.pin_num;
                    this.pin.rotate = editData.rotate;

                    if(editData.type!="SELF"){
                        var baseDataChange = false,
                            typeDataChange = false;
                        if(this.config.outOffset.x == editData.outOffset.x/1
                            && this.config.outOffset.y == editData.outOffset.y/1
                            && this.config.inOffset.x == editData.inOffset.x/1
                            && this.config.inOffset.y == editData.inOffset.y/1
                            && this.config.drillOption.w == editData.drillOption.w/1
                            && this.config.drillOption.h == editData.drillOption.h/1
                            && this.config.drillOption.r == editData.drillOption.r/1
                            && this.config.pinType == editData.pinType
                            && this.config.type == editData.type){
                                baseDataChange = true;
                            }

                        this.config.pinType = editData.pinType;
                        this.config.type = editData.type;

                        this.config.outOffset.x = editData.outOffset.x/1;
    
                        this.config.outOffset.y = editData.outOffset.y/1;
    
                        this.config.inOffset.x = editData.inOffset.x/1;
    
                        this.config.inOffset.y = editData.inOffset.y/1;
    
                        this.config.drillOption.w = editData.drillOption.w/1;
    
                        this.config.drillOption.h = editData.drillOption.h/1;
    
                        this.config.drillOption.r = editData.drillOption.r/1;
    
                        if(editData.type === "C" || editData.type === "OC" || editData.type === "POLY"){
                            if(this.config.r == editData.r / 1){
                                typeDataChange = true;
                            }
                            this.config.r = Number(editData.r);
                            console.log(this.config.r);
                            if(editData.type === "POLY"){
                                if(this.config.num == editData.num / 1){
                                    typeDataChange = true;
                                }
                                this.config.num = Number(editData.num);
                            }
                        }
                        if(editData.type === "S" || editData.type === "CS" || editData.type === "OV"){
                            if(this.config.w == editData.w / 1 && this.config.h == editData.h / 1){
                                typeDataChange = true;
                            }
                            this.config.w = Number(editData.w);
                            this.config.h = Number(editData.h);
                        }
                        if(typeDataChange && baseDataChange){
                            return;
                        }
                        this.pad = generateFigure.pad(this.config);
                        if(this.pinList.length === 1){
                            this.pad.id = this.pinInfo.padid;
                            this.padList[0] = this.pad;
                        }else{
                            let lastPin = this.pinList[this.pinList.length - 2];
                            if(lastPin instanceof Array){
                                console.log(lastPin[0].padid,this.pin.padid)
                            }
                            if((lastPin instanceof Array && lastPin[0].padid == this.pin.padid) || lastPin.padid  == this.pin.padid){
                                this.pad.id = ++this.pinInfo.padid;
                                this.padList.push(this.pad);
                                this.pin.padid = this.pad.id;
                            }else{
                                this.pad.id = this.pin.padid;
                                this.padList[padList.length - 1] = this.pad;
                                // console.log(pad,pin,padList)
                            }
                        }
                    }
                },

                backout(){
                    if(this.pinList.length == 1){
                        return;
                    }
                    // 判断上一个pin引用的是否是这个padid
                    let pin = this.pinList[this.pinList.length - 2];
                    if(pin instanceof Array){
                        if(this.pinList.length == 2){
                            this.pinList.shift();
                            return;
                        }
                        this.pinInfo.pinid -= pin.length;
                        this.pinList.splice(-2,1);
                        return;
                    }else{
                        this.pinInfo.pinid--;
                    }
                    
                    this.pinInfo.pin_num--;

                    this.pinList.pop();


                    this.pin = this.pinList[this.pinList.length - 1];

                    return returnEditData(this.pin,this.config);
                },

                save(type){
                    if(type!=="once"){
                        this.pinList.pop();
                        this.pinList.pop();
                    }
                    if(!this.createNewPin){
                        pinList.pop();
                    }

                    return {
                        pins:this.pinList.flat(),
                        pads:this.padList
                    }
                },

                getData(){
                    return handleUtil.handlerPinDraw(pinList.flat(),padList);
                },
            }
        },

        line(options){
            return {
                path:[],

                line:{},

                createNew:false,

                config:{
                    // 线条宽度
                    width: options.units === "mm"?0.5:10,

                    // 所在层级
                    layer: options.layer || "st",

                    form:"LINE"
                },

                clickEvent(point){
                    
                    this.line = generateFigure.createLine(this.config);

                    if(this.path.length === 0 && point){
                        this.line.data.st_x = point.x;
                        this.line.data.st_y = point.y;
                        this.line.data.sp_x = point.x;
                        this.line.data.sp_y = point.y;
                    }else{
                        this.line.data.st_x = this.path[this.path.length - 1].data.sp_x;
                        this.line.data.st_y = this.path[this.path.length - 1].data.sp_y;
                        this.line.data.sp_x = this.path[this.path.length - 1].data.sp_x;
                        this.line.data.sp_y = this.path[this.path.length - 1].data.sp_y;
                    }

                    this.path.push(this.line);

                    return this.line;
                },

                moveEvent(point){
                    if(!this.path.length){
                        return {};
                    }
                    if(this.createNew){
                        this.clickEvent();
                        this.createNew = false;
                    }
                    this.line.data.sp_x = point.x;
                    this.line.data.sp_y = point.y;

                    return this.line;
                },

                backout(){
                    let line = this.path.splice(-2,1)[0];
                    if(this.path.length){
                        this.line.data.st_x = line.data.st_x;
                        this.line.data.st_y = line.data.st_y;
                    }
                    return this.line;
                },

                edit(eLine){
                    this.path.forEach((line)=>{
                        line.layer = eLine.layer;
                        line.data.width = eLine.data.width;
                    });
                    if(this.line.data.sp_x !== eLine.data.sp_x || this.line.data.sp_y !== eLine.data.sp_y){
                        this.createNew = true;
                    }
                    this.config.layer = eLine.layer;
                    this.config.width = eLine.data.width;
                    this.line.data.sp_x = eLine.data.sp_x;
                    this.line.data.sp_y = eLine.data.sp_y;
                },

                save(type){
                    if(type === "once"){
                        this.path.splice(-1,1);
                    }else{
                        this.path.splice(-3,3);
                    }
                    
                    let saveData = this.clearInvalidLine(this.path);
                    return saveData;
                },

                // 清除无效线条
                clearInvalidLine(paths){
                    return paths.filter((line)=>{
                        return line.data.st_x != line.data.sp_x || line.data.st_y != line.data.sp_y;
                    });
                },

                getData(){
                    return this.path;
                }
            }
        },

        arc(options){
            return {
                path:[],

                arc:{},

                createNew:true,

                config:{
                    // 线条宽度
                    width: options.units === "mm"?0.5:10,

                    // 所在层级
                    layer: options.layer || "st",

                    form:"ARC",

                    arc_r:"nil"
                },

                clickEvent(point){
                    if(this.createNew){
                        this.createNew = false;
                        let arc = generateFigure.createLine(this.config);
                        arc.data.st_x = point.x;
                        arc.data.st_y = point.y;
                        arc.data.sp_x = point.x;
                        arc.data.sp_y = point.y;

                        this.arc = arc;

                        this.path.push(arc);
                        
                    }else{
                        this.createNew = true;
                    }

                    return this.arc;
                },

                moveEvent(point){
                    if(!this.path.length || this.createNew){
                        return {};
                    }
                    
                    this.arc.data.sp_x = point.x;
                    this.arc.data.sp_y = point.y;
                    this.arc.data = util.computedArc(this.arc.data);
                    return this.arc;
                },

                backout(){
                    if(this.createNew){
                        this.createNew = false;
                        return;
                    }
                    
                    this.path.pop();

                    this.arc = this.path[this.path.length - 1];

                    this.createNew = false;

                    return this.arc;
                },

                edit(eArc){
                    this.path.forEach((arc)=>{
                        arc.layer = eArc.layer;
                    });
                    if(this.arc.data.sp_x !== eArc.data.sp_x || this.arc.data.sp_y !== eArc.data.sp_y || this.arc.data.st_x !== eArc.data.st_x || this.arc.data.st_y !== eArc.data.st_y){
                        this.createNew = true;
                        this.arc.data.sp_x = eArc.data.sp_x;
                        this.arc.data.sp_y = eArc.data.sp_y;
                        this.arc.data.st_x = eArc.data.st_x;
                        this.arc.data.st_y = eArc.data.st_y;
                        this.arc.data = util.computedArc(this.arc.data);
                    }
                    this.arc.data.width = eArc.data.width;
                    this.arc.data.arc_r = eArc.data.arc_r;
                    this.config.layer = eArc.layer;
                    this.config.width = eArc.data.width;
                    this.config.arc_r = eArc.data.arc_r;
                },

                save(){
                    if(!this.createNew){
                        this.path.splice(-2,2);
                    }
                    
                    let saveData = this.clearInvalidLine(this.path);
                    return saveData;
                },

                // 清除无效线条
                clearInvalidLine(paths){
                    return paths.filter((line)=>{
                        return line.data.st_x != line.data.sp_x || line.data.st_y != line.data.sp_y;
                    });
                },

                getData(){
                    return this.path;
                }
            
            }
        },

        path(options){
            return {
                path:[],

                line:{},

                createNew:false,

                config:{
                    // 线条宽度
                    width: options.units === "mm"?0.5:10,

                    // 所在层级
                    layer: options.layer || "st",

                    form:"LINE",
                    
                    arc_r:"nil"
                },

                clickEvent(point){
                    
                    this.line = generateFigure.createLine(this.config);

                    if(this.path.length === 0 && point){
                        this.line.data.st_x = point.x;
                        this.line.data.st_y = point.y;
                        this.line.data.sp_x = point.x;
                        this.line.data.sp_y = point.y;
                    }else{
                        this.line.data.st_x = this.path[this.path.length - 1].data.sp_x;
                        this.line.data.st_y = this.path[this.path.length - 1].data.sp_y;
                        this.line.data.sp_x = this.path[this.path.length - 1].data.sp_x;
                        this.line.data.sp_y = this.path[this.path.length - 1].data.sp_y;
                    }

                    this.path.push(this.line);

                    return this.line;
                },

                moveEvent(point){
                    if(!this.path.length){
                        return {};
                    }
                    if(this.createNew){
                        this.clickEvent();
                        this.createNew = false;
                    }
                    this.line.data.sp_x = point.x;
                    this.line.data.sp_y = point.y;

                    if(this.line.form == "ARC"){
                        this.line.data = util.computedArc(this.line.data);
                    }

                    return this.line;
                },

                backout(){
                    let line = this.path.splice(-2,1)[0];
                    if(this.path.length){
                        this.line.data.st_x = line.data.st_x;
                        this.line.data.st_y = line.data.st_y;
                    }
                    return this.line;
                },

                edit(eLine){
                    this.path.forEach((line)=>{
                        line.layer = eLine.layer;
                        line.data.width = eLine.data.width;
                    });

                    if(this.line.data.sp_x !== eLine.data.sp_x || this.line.data.sp_y !== eLine.data.sp_y){
                        this.createNew = true;
                        this.line.data.sp_x = eLine.data.sp_x;
                        this.line.data.sp_y = eLine.data.sp_y;
                    }
                    this.config.layer = eLine.layer;
                    this.config.width = eLine.data.width;
                    this.config.form = eLine.form;
                    
                    this.line.form = eLine.form;
                    this.line.data.name = eLine.form;

                    if(this.line.form == "ARC"){
                        this.line.data = util.computedArc(this.line.data);
                        this.line.data.arc_r = eLine.data.arc_r;
                    }
                },

                save(type){
                    if(type === "once"){
                        this.path.splice(-1,1);
                    }else{
                        this.path.splice(-3,3);
                    }
                    let saveData = this.clearInvalidLine(this.path);
                    return saveData;
                },

                // 清除无效线条
                clearInvalidLine(paths){
                    return paths.filter((line)=>{
                        return line.data.st_x != line.data.sp_x || line.data.st_y != line.data.sp_y;
                    });
                },

                getData(){
                    return this.path;
                }
            }
        },

        rect(options){
            options.type = "S";
            return this._AkinRect(options);
        },

        oval(options){
            options.type = "OV";
            return this._AkinRect(options);
        },

        _AkinRect(options){
            return {
                rectList:[],

                rect:{},

                createNew:true,

                config:{
                    // 线条宽度
                    width: options.units === "mm"?0.5:10,

                    // 所在层级
                    layer: options.layer || "st",

                    form: options.type,

                    arc_r:"nil"
                },

                clickEvent(point){
                    if(this.createNew){
                        this.createNew = false;
                        
                        let rect = generateFigure.createAkinRect(this.config);

                        rect.data.x = point.x;
                        rect.data.y = point.y;

                        this.rect = rect;

                        this.rectList.push(rect);
                        
                    }else{
                        this.createNew = true;
                    }

                    return this.rect;
                },

                moveEvent(point){
                    if(!this.rectList.length || this.createNew){
                        return {};
                    }
                    
                    this.rect.data.w = Math.abs(point.x - this.rect.data.x) * 2;
                    this.rect.data.h = Math.abs(point.y - this.rect.data.y) * 2;

                    return this.rect;
                },

                backout(){
                    if(this.createNew){
                        this.createNew = false;
                        return;
                    }
                    
                    this.rectList.pop();

                    this.rect = this.rectList[this.rectList.length - 1];

                    this.createNew = false;

                    return this.rect;
                },

                edit(eRect){
                    this.rectList.forEach((rect)=>{
                        rect.layer = eRect.layer;
                    });
                    if(this.rect.data.w !== eRect.data.w || this.rect.data.h !== eRect.data.h){
                        this.createNew = true;
                        this.rect.data.w = eRect.data.w;
                        this.rect.data.h = eRect.data.h;
                    }
                    this.rect.data.rotate = eRect.data.rotate;
                    this.rect.data.x = eRect.data.x;
                    this.rect.data.y = eRect.data.y;
                    this.rect.data.width = eRect.data.width;
                },

                save(type){
                    if(type == "once"){
                        if(!this.createNew){
                            this.rectList.splice(-1,1);
                        }
                    }else{
                        if(!this.createNew){
                            this.rectList.splice(-2,2);
                        }else{
                            this.rectList.splice(-1,1);
                        }
                    }
                    
                    let saveData = this.clearInvalidRect(this.rectList);
                    return saveData;
                },

                // 清除无效线条
                clearInvalidRect(rectList){
                    return rectList.filter((rect)=>{
                        return rect.data.w != 0 || rect.data.h != 0;
                    });
                },

                getData(){
                    return this.rectList;
                }
            }
        },

        circle(options){
            return {
                path:[],

                arc:{},

                status:0,

                config:{
                    // 线条宽度
                    width:options.units === "mm"?0.5:10,

                    // 所在层级
                    layer: options.layer || "st",

                    form:"ARC",

                    arc_r:"nil"
                },

                clickEvent(point){

                    if(this.status == 0){
                        this.status++;

                        let arc = generateFigure.createLine(this.config);
                        arc.data.o_x = point.x;
                        arc.data.o_y = point.y;

                        this.arc = arc;

                        this.path.push(arc);
                        
                    }else{
                        if(this.status == 3){
                            this.status = 0;
                            return;
                        }else if(this.status == 2){

                            let computedPoint = util.computedLineInCircle(point,{x:this.arc.data.o_x,y:this.arc.data.o_y},this.arc.data.r);
                            this.arc.data.st_x = computedPoint.x;
                            this.arc.data.st_y = computedPoint.y;
                            this.arc.data.sp_x = computedPoint.x;
                            this.arc.data.sp_y = computedPoint.y;

                            // this.drawObj.drawTop.clear();
                        }
                        this.status++;
                    }

                    return this.arc;
                },

                moveEvent(point){
                    if(!this.path.length || this.status == 0){
                        return {};
                    }
                    if(this.status == 1){
                        this.arc.data.r = Math.sqrt((this.arc.data.o_x - point.x) ** 2 + (this.arc.data.o_y - point.y) ** 2);
                    }
                    else if(this.status == 2){
                        let computedPoint = util.computedLineInCircle(point,{x:this.arc.data.o_x,y:this.arc.data.o_y},this.arc.data.r);
                        this.arc.data.st_x = computedPoint.x;
                        this.arc.data.st_y = computedPoint.y;
                        this.arc.data.sp_x = computedPoint.x;
                        this.arc.data.sp_y = computedPoint.y;
                    }else if(this.status == 3){
                        let computedPoint = util.computedLineInCircle(point,{x:this.arc.data.o_x,y:this.arc.data.o_y},this.arc.data.r);
                        this.arc.data.sp_x = computedPoint.x;
                        this.arc.data.sp_y = computedPoint.y;
                    }
                    
                    return this.arc;
                },

                backout(){
                    if(this.status == 1){
                        this.status = 0;
                        this.path.pop();
                        this.arc = this.path[this.path.length - 1];
                        return;
                    }
                    if(this.status == 2){
                        this.status = 1;
                        this.arc.data.st_x = 0;
                        this.arc.data.st_y = 0;
                        return;
                    }

                    if(this.status == 3){
                        this.status = 2;
                        this.arc.data.sp_x = this.arc.data.st_x;
                        this.arc.data.sp_y = this.arc.data.st_y;
                        return;
                    }

                    if(this.status == 0){
                        this.status = 3;
                        return;
                    }

                    return this.arc;
                },

                edit(eArc){
                    this.path.forEach((arc)=>{
                        arc.layer = eArc.layer;
                    });
                    if(this.arc.data.r != eArc.data.r && this.status == 1){
                        this.status = 2;
                        this.arc.data.r = eArc.data.r;
                    }

                    this.arc.data.width = eArc.data.width;
                    this.arc.data.arc_r = eArc.data.arc_r;
                    this.arc.data.o_x = eArc.data.o_x;
                    this.arc.data.o_y = eArc.data.o_y;

                    this.config.layer = eArc.layer;
                    this.config.width = eArc.data.width;
                    this.config.arc_r = eArc.data.arc_r;
                },

                save(type){
                    if(type == "once"){
                        if(this.status != 0){
                            this.path.splice(-1,1);
                        }
                    }else{
                        if(this.status < 2){
                            this.path.splice(-2,2);
                        }else{
                            this.path.splice(-1,1);
                        }
                    }
                    
                    let saveData = this.clearInvalidLine(this.path);
                    return saveData;
                },

                // 清除无效线条
                clearInvalidLine(paths){
                    return paths.filter((line)=>{
                        return !!line.data.r;
                    });
                },

                getData(){
                    return this.path;
                }
            }
        },

        pathShape(options){
            return {
                shapes:[],

                shape:{},

                lineData:{},

                startLineData:{},

                endLineData:{},

                createNew:false,

                createNewShape:true,

                config:{
                    // 所在层级
                    layer: options.layer || "st",

                    form:"LINE",
                    
                    arc_r:"t"
                },

                clickEvent(point){

                    if(this.createNewShape){
                        this.shape = {
                            form:"PATH",
                            layer:this.config.layer,
                            type:"shapes",
                            make:"o",
                            data:[]
                        };
                        this.shapes.push(this.shape);   
                        this.createNewShape = false;
                    }
                    if(this.shape.data.length === 0){
                        this.config.form = "LINE";
                        this.lineData = generateFigure.createLineData(this.config);
                        this.endLineData = generateFigure.createLineData(this.config);
                        this.lineData.st_x = point.x;
                        this.lineData.st_y = point.y;
                        this.lineData.sp_x = point.x;
                        this.lineData.sp_y = point.y;
                        this.startLineData = this.lineData;
                        this.endLineData.sp_x = this.startLineData.st_x;
                        this.endLineData.sp_y = this.startLineData.st_y;
                        this.shape.data.push(this.lineData);
                        this.shape.data.push(this.endLineData);

                    }else{
                        if(this.lineData.sp_x == this.startLineData.st_x && this.lineData.sp_y == this.startLineData.st_y){
                            this.shape.data.pop();
                            this.createNewShape = true;
                            return {};
                        }
                        if(this.lineData.st_x == this.lineData.sp_x && this.lineData.st_y == this.lineData.sp_y){
                            this.createNewShape = true;
                            return {};
                        }
                        this.lineData = generateFigure.createLineData(this.config);
                        this.lineData.st_x = this.shape.data[this.shape.data.length - 2].sp_x;
                        this.lineData.st_y = this.shape.data[this.shape.data.length - 2].sp_y;
                        this.lineData.sp_x = this.shape.data[this.shape.data.length - 2].sp_x;
                        this.lineData.sp_y = this.shape.data[this.shape.data.length - 2].sp_y;
                        this.shape.data.splice(-1,0,this.lineData);
                    }

                    return {...this.lineData,layer:this.config.layer,make:this.shape.make};
                },

                moveEvent(point){
                    if(!this.shape || !this.shape.data || !this.shape.data.length || this.createNewShape){
                        return {};
                    }
                    if(this.createNew){
                        this.lineData = generateFigure.createLineData(this.config);
                        this.lineData.st_x = this.shape.data[this.shape.data.length - 1].sp_x;
                        this.lineData.st_y = this.shape.data[this.shape.data.length - 1].sp_y;
                        this.lineData.sp_x = this.shape.data[this.shape.data.length - 1].sp_x;
                        this.lineData.sp_y = this.shape.data[this.shape.data.length - 1].sp_y;
                        this.shape.data.splice(-1,0,this.lineData);
                        this.createNew = false;
                    }
                    this.lineData.sp_x = point.x;
                    this.lineData.sp_y = point.y;
                    if(this.lineData.name == "ARC"){
                        let h = util.computedArc(this.lineData);
                        this.lineData.r = h.r;
                        this.lineData.o_x = h.o_x;
                        this.lineData.o_y = h.o_y;
                    }
                    this.endLineData.st_x = point.x;
                    this.endLineData.st_y = point.y;

                    let result = {
                        ...util.copyObject(this.lineData),
                        layer:this.config.layer,
                        make:this.shape.make
                    }

                    if(this.startLineData === this.lineData){
                        result.first = true;
                    }

                    return result;
                },

                backout(){
                    if(this.createNewShape){
                        this.createNewShape = false;
                        this.endLineData = this.shape.data[this.shape.data.length - 1];
                        this.lineData = this.shape.data[this.shape.data.length - 2];
                    }else{
                        let lastLine = this.shape.data.splice(-2,1)[0];
                        this.endLineData.st_x = lastLine.st_x;
                        this.endLineData.st_y = lastLine.st_y;
                        this.lineData = this.shape.data[this.shape.data.length - 2];
                        if(this.shape.data.length === 1){
                            this.shapes.pop();
                            this.shape = this.shapes[this.shapes.length - 1];
                            this.createNewShape = true;
                        }
                    }
                },

                edit(eLine){
                    this.shapes.forEach((shape)=>{
                        shape.layer = eLine.layer;
                    });
                    if(this.lineData.sp_x !== eLine.sp_x || this.lineData.sp_y !== eLine.sp_y){
                        this.createNew = true;
                    }
                    this.config.layer = eLine.layer;
                    this.config.arc_r = eLine.arc_r;
                    this.config.form = eLine.name;
                    this.lineData.sp_x = eLine.sp_x;
                    this.lineData.sp_y = eLine.sp_y;
                    this.endLineData.st_x = this.lineData.sp_x;
                    this.endLineData.st_y = this.lineData.sp_y;

                    this.lineData.name = eLine.name;
                    this.lineData.arc_r = eLine.arc_r;

                    this.shape.make = eLine.make;
                    if(eLine.name === "ARC"){
                        let h = util.computedArc(this.lineData);
                        this.lineData.r = h.r;
                        this.lineData.o_x = h.o_x;
                        this.lineData.o_y = h.o_y;
                    }
                },

                save(type){
                    if(type === "once"){
                        if(!this.createNewShape){
                            let lastLine = this.shape.data.splice(-2,1)[0];
                            this.endLineData.st_x = lastLine.st_x;
                            this.endLineData.st_y = lastLine.st_y;
                        }
                    }

                    return this.clearInvalidShape(this.shapes);
                },

                // 过滤无效铜皮
                clearInvalidShape(shapes){
                    return shapes.filter((shape)=>{
                        shape.data = shape.data.filter(line=>{
                            return line.st_x != line.sp_x || line.st_y != line.sp_y;
                        });
                        if(shape.data.length < 2){
                            return false;
                        }
                        if(shape.data.length == 2){
                            if(shape.data[1].name == "ARC"){
                                return true;
                            }
                            return false;
                        }
                        return true;
                    });
                },

                getData(){
                    return this.shapes;
                }
            }
        },

        circleShape(options){
            return {
                shapes:[],

                shape:{},

                circleData:{},

                createNewShape:true,

                config:{
                    // 所在层级
                    layer: options.layer || "st",

                    form:"ARC",

                    make:"o"
                },

                clickEvent(point){

                    if(this.createNewShape){
                        this.shape = {
                            form:"PATH",
                            layer:this.config.layer,
                            type:"shapes",
                            make:this.config.make,
                            data:[]
                        };
                        
                        this.circleData = generateFigure.createLineData(this.config);

                        this.circleData.o_x = point.x;
                        this.circleData.o_y = point.y;

                        this.shape.data.push(this.circleData);

                        this.shapes.push(this.shape);  

                        this.createNewShape = false;
                    }else{
                        this.circleData.r = Math.sqrt(Math.pow(this.circleData.o_x - point.x,2) + Math.pow(this.circleData.o_y - point.y,2));
                        this.createNewShape = true;
                    }

                    return {...this.circleData,layer:this.config.layer,make:this.shape.make,r: this.circleData.r * 2};
                },

                moveEvent(point){
                    if(this.createNewShape){
                        return {...this.circleData,layer:this.config.layer,make:this.shape.make,r: this.circleData.r * 2};
                    }

                    this.circleData.r = Math.sqrt(Math.pow(this.circleData.o_x - point.x,2) + Math.pow(this.circleData.o_y - point.y,2));

                    let result = {
                        ...this.circleData,
                        layer:this.config.layer,
                        make:this.shape.make,
                        r:this.circleData.r * 2
                    }

                    return result;
                },

                backout(){
                    if(this.createNewShape){
                        this.createNewShape = false;
                    }else{
                        this.shapes.pop();

                        this.shape = this.shapes[this.shapes.length - 1];

                        this.circleData = this.shape.data[0];

                        this.createNewShape = true;
                    }
                },

                edit(eCircle){
                    this.shapes.forEach((shape)=>{
                        shape.layer = eCircle.layer;
                    });

                    if(this.circleData.r !== eCircle.r / 2){
                        this.createNewShape = true;
                        this.circleData.r = eCircle.r / 2
                    }
                    this.circleData.o_x = eCircle.o_x;
                    this.circleData.o_y = eCircle.o_y;

                    this.shape.make = eCircle.make;

                },

                save(type){
                    if(!this.createNewShape){
                          this.shapes.pop();  
                    }

                    return this.clearInvalidShape(this.shapes);
                },

                // 过滤无效铜皮
                clearInvalidShape(shapes){
                    return shapes.filter((shape)=>{
                        return shape.data[0].r != 0;
                    });
                },

                getData(){
                    return this.shapes;
                }
            }
        },

        rectShape(options){

            function rectData2LineData(rectData){
                return toOriginMathods.rect2Path(rectData);
            }

            return {
                shapes:[],

                shape:{},

                rectData:{},

                createNewShape:true,

                config:{
                    // 所在层级
                    layer: options.layer || "st",

                    make:"o"
                },

                clickEvent(point){
                    if(this.createNewShape){
                        this.shape = {
                            form:"PATH",
                            layer:this.config.layer,
                            type:"shapes",
                            make:this.config.make,
                            data:[]
                        };
                        
                        this.rectData = {
                            x: point.x,
                            y: point.y,
                            w:0,
                            h:0
                        };

                        this.shapes.push(this.shape);  

                        this.createNewShape = false;
                    }else{
                        this.shape.data = rectData2LineData(this.rectData);
                        this.createNewShape = true;
                    }

                    return {...this.rectData,layer:this.config.layer,make:this.shape.make};
                },

                moveEvent(point){
                    if(this.createNewShape){
                        return {...this.circleData,layer:this.config.layer,make:this.shape.make};
                    }

                    this.rectData.w = Math.abs(this.rectData.x - point.x) * 2;

                    this.rectData.h = Math.abs(this.rectData.y - point.y) * 2;
                    
                    this.shape.data = rectData2LineData(this.rectData);

                    return {...this.rectData,layer:this.config.layer,make:this.shape.make};
                },

                backout(){
                    if(this.createNewShape){
                        this.createNewShape = false;
                    }else{
                        this.shapes.pop();

                        this.shape = this.shapes[this.shapes.length - 1];

                        // this.circleData = this.shape.data[0];

                        this.createNewShape = true;
                    }
                },

                edit(eRect){
                    this.shapes.forEach((shape)=>{
                        shape.layer = eRect.layer;
                    });

                    if(this.rectData.w !== eRect.w || this.rectData.h !== eRect.h){
                        this.createNewShape = true;
                        this.rectData.w = eRect.w;
                        this.rectData.h = eRect.h;
                    }

                    this.rectData.x = eRect.x;
                    this.rectData.y = eRect.y;

                    this.shape.data = rectData2LineData(this.rectData);
                    this.shape.make = eRect.make;

                },

                save(type){
                    if(!this.createNewShape){
                          this.shapes.pop();  
                    }

                    return this.clearInvalidShape(this.shapes);
                },

                // 过滤无效铜皮
                clearInvalidShape(shapes){
                    return shapes.filter((shape)=>{
                        shape.data = shape.data.filter(line=>{
                            return line.st_x != line.sp_x || line.st_y != line.sp_y;
                        });
                        if(shape.data.length < 2){
                            return false;
                        }
                        return true;
                    });
                },

                getData(){
                    return this.shapes;
                }
            }
        },

        text(options){
            let config = {
                layer: options.layer || "st",
                content:"",
                textblock:2
            };

            let initalText = generateFigure.createText(config);
            
            return {
                texts:[initalText],

                text:initalText,

                config,

                createNew:false,

                clickEvent(point){
    
                        this.text = generateFigure.createText(this.config);
    
                        this.text.data.x = point.x;
                        this.text.data.y = point.y;
    
                        this.texts.push(this.text);

                        return this.text;
                },

                moveEvent(point){
                    if(this.createNew){
                        this.text = generateFigure.createText(this.config);
                        this.texts.push(this.text);
                        this.createNew = false;
                    }
                    this.text.data.x = point.x;
                    this.text.data.y = point.y;

                    return this.text;
                },

                backout(){
                    if(this.texts.length == 1){
                        return;
                    }
                    this.texts.pop();
                    this.text = this.texts[this.texts.length - 1];
                },

                edit(eText){
                    this.config.layer = eText.layer;
                    if(this.texts.length === 0){
                        return;
                    }
                    if(eText.data.x != this.text.data.x || eText.data.y != this.text.data.y){
                        this.createNew = true;
                        this.text.data.x = eText.data.x;
                        this.text.data.y = eText.data.y;
                    }
                    this.texts.forEach(text=>{
                        text.layer = eText.layer;
                    });
                    this.text.data.rotate = eText.data.rotate;
                    this.text.data.content = String(eText.data.content);
                    this.text.data.textblock = eText.data.textblock;
                    this.text.data.textheight = this.text.data.textblock;
                    this.text.data.textwidth = this.text.data.textblock * this.text.data.content.length;

                    this.config.textblock = eText.data.textblock;
                },

                save(type){
                    if(type!=="once"){
                        this.texts.pop();
                        this.texts.pop();
                    }
                    if(!this.createNew){
                        this.texts.pop();
                    }

                    return this.texts;
                },

                getData(){
                    return this.texts;
                }
            }
        },

        // 一脚标识
        onePinMark(options){
            var config = {
                r: options.units == "mm" ? 0.8 : 31.496,
                x: 0,
                y: 0,
                rotate: 0
            }

            var initalOnePinMark = generateFigure.createOnePinTMark(config);

            function drawData(onePinMarkList){
                let draw = onePinMarkList.flat();
                return draw;
            }

            return {
                onePinMarkList:[initalOnePinMark],

                onePinMark:initalOnePinMark,

                config,

                createNew:false,

                clickEvent(point){
                        this.config.x = point.x;
                        this.config.y = point.y;

                        this.onePinMark = generateFigure.createOnePinTMark(this.config);
    
                        this.onePinMarkList.push(this.onePinMark);

                        return this.config;
                },

                moveEvent(point){
                    this.config.x = point.x;
                    this.config.y = point.y;

                    this.onePinMark = generateFigure.createOnePinTMark(this.config);

                    if(this.createNew){
                        this.onePinMarkList.push(this.onePinMark);
                        this.createNew = false;
                    }else{
                        this.onePinMarkList[this.onePinMarkList.length - 1] = this.onePinMark;
                    }
                    return this.config;
                },

                backout(){
                    if(this.onePinMarkList.length == 1){
                        return;
                    }
                    this.onePinMarkList.pop();
                    this.onePinMark = this.onePinMarkList[this.onePinMarkList.length - 1];
                },

                edit(eOnePinMark){
                    if(this.onePinMarkList.length === 0){
                        return;
                    }
                    this.config.rotate = eOnePinMark.rotate;
                    if(eOnePinMark.x != this.config.x || eOnePinMark.y != this.config.y){
                        this.createNew = true;
                        this.config.x = eOnePinMark.x;
                        this.config.y = eOnePinMark.y;
                    }
                    this.config.r = eOnePinMark.r;
                    this.onePinMark = generateFigure.createOnePinTMark(this.config);
                    this.onePinMarkList[this.onePinMarkList.length - 1] = this.onePinMark;
                },

                save(type){
                    if(type!=="once"){
                        this.onePinMarkList.pop();
                        this.onePinMarkList.pop();
                    }
                    if(!this.createNew){
                        this.onePinMarkList.pop();
                    }

                    return drawData(this.onePinMarkList);
                },

                getData(){
                    return drawData(this.onePinMarkList);
                }
            }
        },

        // 一脚圆标识
        onePinCMark(options){
            var config = {
                r: options.units == "mm" ? 0.8 : 31.496
            }

            var initalCMark = generateFigure.createOnePinCMark(config);

            function editData(config,onePinMark){
                var cMark = util.copyObject(onePinMark);

                var edit = {
                    r: config.r,
                    o_x: onePinMark.data.o_x,
                    o_y: onePinMark.data.o_y
                }

                cMark.data.r *= 2;

                return edit;
            }

            return {
                onePinMarkList:[initalCMark],

                onePinMark:initalCMark,

                config,

                createNew:false,

                clickEvent(point){

                        this.onePinMark = generateFigure.createOnePinCMark(this.config);

                        this.onePinMark.data.o_x = point.x;
                        this.onePinMark.data.o_y = point.y;
    
                        this.onePinMarkList.push(this.onePinMark);

                        return editData(this.config, this.onePinMark);
                },

                moveEvent(point){

                    if(this.createNew){
                        this.onePinMark = generateFigure.createOnePinCMark(this.config);
                        this.onePinMarkList.push(this.onePinMark);
                        this.createNew = false;
                    }
                    this.onePinMark.data.o_x = point.x;
                    this.onePinMark.data.o_y = point.y;

                    return editData(this.config, this.onePinMark);
                },

                backout(){
                    if(this.onePinMarkList.length == 1){
                        return;
                    }
                    this.onePinMarkList.pop();
                    this.onePinMark = this.onePinMarkList[this.onePinMarkList.length - 1];
                },

                edit(eOnePinMark){
                    if(this.onePinMarkList.length === 0){
                        return;
                    }
                    if(eOnePinMark.o_x != this.onePinMark.data.o_x || eOnePinMark.o_y != this.onePinMark.data.o_y){
                        this.createNew = true;
                        this.onePinMark.data.o_x = eOnePinMark.o_x;
                        this.onePinMark.data.o_y = eOnePinMark.o_y;
                    }
                    if(eOnePinMark.r != this.config.r){
                        this.config.r = eOnePinMark.r;
                        var newOnePinMark = generateFigure.createOnePinCMark(this.config);
                        newOnePinMark.data.o_x = this.onePinMark.data.o_x;
                        newOnePinMark.data.o_y = this.onePinMark.data.o_y;
                        this.onePinMark = newOnePinMark;
                        this.onePinMarkList[this.onePinMarkList.length - 1] = this.onePinMark;
                    }
                },

                save(type){
                    if(type!=="once"){
                        this.onePinMarkList.pop();
                        this.onePinMarkList.pop();
                    }
                    if(!this.createNew){
                        this.onePinMarkList.pop();
                    }

                    return this.onePinMarkList;
                },

                getData(){
                    return this.onePinMarkList;
                }
            }
        },

        // 复制图形
        copyBoxChooseImage(options){
            var originImage = options.copyImages;
            var center = {
                x: (options.range.x[0] + options.range.x[1]) / 2,
                y: (options.range.y[0] + options.range.y[1]) / 2
            }
            console.log(options.pinLength,options.pins_id);
            var imageConfig = {
                pins_id: options.pins_id,
                pinLength : options.pinLength
            }

            var copyImage = getNewCopyImage(originImage);

            var copyImageList = [copyImage];

            var config = {
                x: 0,
                y: 0
            }

            function getNewCopyImage(imgList){
                imgList = util.copyObject(imgList);
                var updatePinId = {};
                imgList.forEach(img=>{
                    if(img.type == "pins"){
                        if(!updatePinId[img.pinid]){
                            updatePinId[img.pinid] = ++imageConfig.pins_id;
                        }
                        img.pinid = updatePinId[img.pinid];
                    }
                });
                return imgList;
            }

            function getCopyImage(){
                return getNewCopyImage(originImage);
            }

            function moveImages(imgList,offset){
                imgList = util.copyObject(imgList);
                imgList.forEach(img=>{
                    if(img.type == "pins" || img.form == "S" ||  img.form == "OV" ||  img.form == "OC" || img.type == "texts"){
                        img.data.x += offset.x;
                        img.data.y += offset.y;
                        return;
                    }
                    if(img.type == "path"){
                        img.data.st_x += offset.x;
                        img.data.st_y += offset.y;
                        img.data.sp_x += offset.x;
                        img.data.sp_y += offset.y;
                        if(img.form == "ARC"){
                            img.data.o_x += offset.x;
                            img.data.o_y += offset.y;
                        }
                        return;
                    }
                    if(img.type == "shapes"){
                        img.data.forEach(line=>{
                            line.st_x += offset.x;
                            line.st_y += offset.y;
                            line.sp_x += offset.x;
                            line.sp_y += offset.y;
                            if(line.name == "ARC"){
                                line.o_x += offset.x;
                                line.o_y += offset.y;
                            }
                        });
                    }
                });
                return imgList;
            }

            return {
                createNew:false,

                clickEvent(point){
                    var offset = {
                        x: point.x - center.x,
                        y: point.y - center.y 
                    }

                    copyImageList[copyImageList.length - 1] = moveImages(copyImage,offset);

                    copyImage = getCopyImage();

                    copyImageList.push(copyImage);

                    copyImageList[copyImageList.length - 1] = moveImages(copyImage,offset);


                    config.x = point.x;
                    config.y = point.y;

                    return config;
                },

                moveEvent(point){
                    var offset = {
                        x: point.x - center.x,
                        y: point.y - center.y 
                    }

                    config.x = point.x;
                    config.y = point.y;

                    if(this.createNew){
                        copyImage = getCopyImage();
                        copyImageList.push(copyImage);
                        this.createNew = false;
                    }
                    copyImageList[copyImageList.length - 1] = moveImages(copyImage,offset);
                    return config;
                },

                backout(){
                    if(copyImageList.length == 1){
                        return;
                    }
                    imageConfig.pins_id -= 2 * imageConfig.pinLength;
                    copyImageList.pop();
                    copyImage = getCopyImage();
                },

                edit(eOnePinMark){
                    if(this.onePinMarkList.length === 0){
                        return;
                    }
                    if(eOnePinMark.o_x != this.onePinMark.data.o_x || eOnePinMark.o_y != this.onePinMark.data.o_y){
                        this.createNew = true;
                        this.onePinMark.data.o_x = eOnePinMark.o_x;
                        this.onePinMark.data.o_y = eOnePinMark.o_y;
                    }
                },

                save(type){
                    if(type!=="once"){
                        copyImageList.pop();
                        copyImageList.pop();
                    }
                    if(!this.createNew){
                        copyImageList.pop();
                    }

                    return copyImageList.flat();
                },

                getData(){
                    return copyImageList.flat();
                }
            }
        }
    }

    // let count = 0;
    function Debugger(val){
        console.log(val);
    }

    //是否是一个空对象
    function isEmpty(obj){
        try{
            if(JSON.stringify(obj) === "{}" || !obj){
                return true;
            }
        }catch(e){
            return false;
        }
        return false;
    }

    /**
     * @param {string} str 
     * @returns
     */
    function makeMap(str,isLowerCase){
        let map = {};
        let arr = str.split(",");
        arr.forEach(item=>{
            map[item] = true;
        });
        return isLowerCase?(str)=>map[str.toUpperCase()]:(str)=>map[str];
    }

    // 工具包
    const util = {
        /**
         * @returns 
         */
        createElement({name,attr,events,value}){
            if(typeof name !== "string"){
                throw "name is error type"
            }
            let element = document.createElement(name);
            if(value){
                element.innerText = value;
            }
            if(attr && typeof attr === "object"){
                this.changeElementAttr(element,attr);
            }
            if(events && typeof events === "object"){
                this.addElementEvent(ele,events);
            }
            return element;
        },

        // 改变节点的属性
        changeElementAttr(ele,attr){
            if(!attr instanceof Object || attr instanceof Array || typeof ele !== "object"){
                return;
            }
            Object.getOwnPropertyNames(attr).forEach(attrname=>{
                let attrData = attr[attrname];
                if(typeof attrData !== "string" && typeof attrData!=="boolean"){
                    this.changeElementAttr(ele[attrname],attrData);
                    return;
                }
                ele[attrname] = attrData;
            });   
        },

        // 给节点添加事件
        addElementEvent(ele,eventList){
            if(typeof eventList !== "object" || !(ele instanceof HTMLElement)){
                return;
            }
            Object.getOwnPropertyNames(eventList).forEach(eventName=>{
                if(typeof eventList[eventName] !== "function"){
                    return;
                }
                ele.addEventListener(eventName,eventList[eventName]);
            });
        },

        // 复制一个对象
        copyObject(obj,options){
            try{
                return JSON.parse(JSON.stringify(obj,options));
            }catch(e){
                return obj;
            }
        },

        /**
         * 
         * @param {HTMLElement|string} parent
         * @returns
         */
        getElement(parent){
            if(typeof parent === "string"){
                let ele = document.querySelector(parent);
                return ele;
            }else{
                if(parent instanceof HTMLElement){
                    return parent;
                }
                return false;
            }
        },

        // 节流器
        throttle(func,interval,fixedThis){
            var saveArgus,
                saveThis,
                isThrottle = false;

            function worker(){
                if(isThrottle){
                    saveArgus = arguments;
                    saveThis = fixedThis || this;
                    return;
                }

                func.apply(this,arguments);
                
                isThrottle = true;

                setTimeout(()=>{
                    isThrottle = false;
                    if(saveArgus){
                        worker.apply(saveThis,saveArgus);
                        saveThis = saveArgus = null;
                    }
                },interval || 16);
            }

            return worker;
        },

        // 防抖
        antiShake(fn,interval,self){
            let timer = 0;
            return function (...args){
                if(timer){
                    clearTimeout(timer);
                }
                timer = setTimeout(()=>{
                    fn.apply(self,args);
                },interval || 100);
            }
        },

        layerMap:makeMap("st,sb,at,ab,sm_t,sm_b,et,eb,bt,bb,pt,pb"),

        pinLayerMap:makeMap("b,bs_t,bs_b,bp_t,bp_b,t,ts_t,ts_b,tp_t,tp_b,i,is_t,is_b,ip_t,ip_b,drill"),

        // 矫正鼠标位置
        revisePoint(point,smallDist){
            let x = point.x , y = point.y;

            if(smallDist.x){
                let remX = point.x % smallDist.x;

                if(remX < 0){
                    x = Math.abs(remX) <= smallDist.x/2 ? point.x - remX : point.x - smallDist.x - remX;
                }else{
                    x = remX<=smallDist.x/2 ? point.x -remX:point.x - remX + smallDist.x;
                }
            }

            if(smallDist.y){
                let remY = point.y % smallDist.y;
                if(remY < 0){
                    y = Math.abs(remY) <= smallDist.y/2 ? point.y - remY : point.y - smallDist.y - remY;
                }else{
                    y = remY<=smallDist.y/2 ? point.y - remY:point.y - remY + smallDist.y;
                }
            }

            return {x:Number(x.toFixed(4)),y:Number(y.toFixed(4))}
        },

        // 计算弧形数据
        computedArc(data){
            // 圆心
            let center = {
                x:(data.st_x + data.sp_x) / 2,
                y:(data.st_y + data.sp_y) / 2
            }
            let r = Math.sqrt(Math.pow(data.st_x - data.sp_x,2) + Math.pow(data.st_y - data.sp_y,2)) / 2;
            return {
                o_x:center.x,
                o_y:center.y,
                st_x:data.st_x,
                st_y:data.st_y,
                sp_x:data.sp_x,
                sp_y:data.sp_y,
                r,
                name:"ARC",
                width:data.width,
                arc_r:data.arc_r
            }
        },

        // 将一点绕中心点进行旋转
        /**
         * 
         * @param {*} point 
         * @param {*} center 
         * @param {*} rotate 
         * @returns 
         */
        rotatePoint(point,center,rotate){
            if(!rotate){
                return point;
            }
            let angle = rotate * Math.PI / 180;
            return [
                (point[0] - center[0]) * Math.cos(angle) - (point[1] - center[1]) * Math.sin(angle) + center[0],
                (point[0] - center[0]) * Math.sin(angle) + (point[1] - center[1]) * Math.cos(angle) + center[1]
            ]
        },

        // 将多个点绕中心进行旋转
        rotatePoints(points,center,rotate){
            return points.map(point=>this.rotatePoint(point,center,rotate));
        },

        // 获取属性的类型
        getRawType(value){
            return Object.prototype.toString.call(value).slice(8,-1);
        },

        // 计算从圆心过某一点的射线与圆的交点
        computedLineInCircle(point,center,r){
            let computedX = 0,computedY = 0;
            if(point.y == center.y && point.x != center.x){
                computedY = point.y;
                if(point.x > center.x){
                    computedX = center.x + r;
                }else{
                    computedX = center.x - r;
                }
            }
            else if(point.x == center.x && point.y != center.y){
                computedX = point.x;
                if(point.y > center.y){
                    computedY = center.y + r;
                }else{
                    computedY = center.y - r;
                }
            }
            else if(point.x != center.x && point.y != center.y){
                let k = (point.y - center.y) / (point.x - center.x);
                computedX = Math.sqrt(r ** 2 / ( k ** 2 + 1));
                if(point.x < center.x){
                    computedX = - computedX;
                }
                computedX += center.x;
                computedY = k * (computedX - center.x) + center.y;
            }
            else{
                computedX = center.x + r;
                computedY = center.y;
            }
            return {
                x:computedX,
                y:computedY
            }
        }
    }

    // 生成pin编号
    const generatePinNumber = {
        // 生成编号
        generateNumber(config){
            console.log(config)
            // let mode=obj.mode;
            let xnum = config.rowNumber;
            let ynum = config.colNumber;
            let txt  = config.startNum.toUpperCase();
            
            let ennum=this.textType(txt);
            let box=[];
            for(let i=0;i<xnum;i++){
                let row=[];
                let br=false;
                if(i>0){
                    br=true;
                }
                for(let j=0;j<ynum;j++){

                    if(i==0 && j==0){
                        row.push(txt);
                    }else{
                        txt=this.textAdd(txt,ennum,br);
                        row.push(txt);
                        ennum=this.textType(txt);
                    }

                    br=false;
                }
                box.push(row);
            }
            return box;

        },

        textType(txt){
            let num=0;
            let test_en= new RegExp("^[A-Za-z]{"+num+"}\\d+$");
            for(let i=0;i<txt.length;i++){
                if(!test_en.test(txt)){
                    num++;
                    test_en=new RegExp("^[A-Za-z]{"+num+"}\\d+$");
                }
            }
            return num;
        },

        //自增
        textAdd(txt,ennum,br){//文本，字母个数，换行
            let text_en=/^[a-zA-Z]+$/,         //字母检测
                text_num=/^[0-9]*[1-9][0-9]*$/;//数字检测
            if(ennum==0){
                return txt/1+1;
            }else{//字母
                let en=txt.substr(0,ennum),
                    num=txt.substring(ennum);

                if(text_en.test(en)&&text_num.test(num)){//字母加数字
                    if(br){
                        txt=en_add(en)+(1);
                    }else{
                        txt=en+(num/1+1);
                    }
                    
                }else if(text_en.test(en)&&!text_num.test(num)){//纯字母
                    txt=en_add(en,br);
                    
                }
                return txt;
            }

            
            function en_add(entxt,br){//纯字母增
                let length=entxt.length-1;
                let en_end=entxt.substring(length);
                let en_new="";
                let en_head=entxt.substr(0,length);
                let enAddlock=true;
                let exclude =["I","O","Q","S","X","Z"]; //需要跳过的字母

                if(en_end.toUpperCase()=="Y"||br){
                    let endnum=-1;
                    if(br){
                        length=length-1;//摒弃最后一位
                    }
                    for(let i=length;i>=0;i--){
                        en_end=entxt.substr(i,length-i+1);
                        if(en_end.toUpperCase()!="Y"){
                            endnum=i;
                            break;
                        }
                    }
                    if(endnum==-1){
                        en_end="Y"
                        endnum=0;
                    }

                    if(br){
                        if(entxt.length==1){
                            en_end=entxt;
                            endnum=0;
                            console.log(en_end)
                        }else{
                            for(let k=endnum;k<length+1;k++){
                                en_new="A"+en_new;
                            }
                        }
                        
                    }else{
                        for(let k=endnum;k<length;k++){
                            en_new="A"+en_new;
                        }
                    }
                    
                    en_head=entxt.substr(0,endnum);
                    if(en_end.toUpperCase()=="Y"){
                        en_end="A";
                        if(en_head==""||en_head==null){
                            en_head="A";
                        }
                    }else{
                        en_end=String.fromCharCode(en_end.charCodeAt(0) + 1);
                        //检测是否是需要跳过的字母
                        exclude.forEach(value=>{
                            if(value==en_end){
                                en_end = String.fromCharCode(en_end.charCodeAt(0) + 1);
                            }
                        });
                    }
                    entxt=en_head+en_end+en_new;
                    
                }else{
                    en_end=String.fromCharCode(en_end.charCodeAt(0) + 1);
                    //检测是否是需要跳过的字母
                    exclude.forEach(value=>{
                        if(value==en_end){
                            en_end = String.fromCharCode(en_end.charCodeAt(0) + 1);
                        }
                    });
                    
                    entxt=en_head+en_end;
                }
                return entxt;
            }
        }
    }

    // canvas管理
    const canvasManager = {
        shareCanvas:null,
        shareCanvasParent:null,
        generateShareCanvas(parentEle,edit,grid){
            let w = parentEle.clientWidth;
            let h = parentEle.clientHeight;
            if(!this.shareCanvas){
                this.edit = edit;
                this.grid = grid;
                this.shareCanvas = this.generateCanvas(parentEle,edit,grid);
                this.shareCanvasParent = this.shareCanvas.canvas_global.parentNode;
                return this.shareCanvas;
            }
            let shareCanvas = {
                canvas_global:this.shareCanvas.canvas_global,
                canvas_shape:this.shareCanvas.canvas_shape,
                canvas_flag: this.shareCanvas.canvas_flag
            };
            if(edit){
                if(!this.shareCanvas.canvas_preview){
                    this.shareCanvas.canvas_preview = this.createCanvas("canvas_preview",0,0);
                }
                if(!this.shareCanvas.canvas_top){
                    this.shareCanvas.canvas_top = this.createCanvas("canvas_top",0,0);
                }
                shareCanvas.canvas_preview = this.shareCanvas.canvas_preview;
                shareCanvas.canvas_top = this.shareCanvas.canvas_top;
            }
            if(grid){
                if(!this.shareCanvas.canvas_grid){
                    this.shareCanvas.canvas_grid = this.createCanvas("canvas_grid",0,0);
                }
                shareCanvas.canvas_grid = this.shareCanvas.canvas_grid;
            }
            this.resize(shareCanvas,[w,h]);
            return shareCanvas;
        },
        /**
         * 
         * @param {HTMLElement} parentEle 
         * @param {boolean} edit 
         * @param {boolean} grid 
         * @returns 
         */
        generateCanvas(parentEle,edit,grid){
            parentEle.innerHTML = "";
            let w = parentEle.clientWidth;
            let h = parentEle.clientHeight;

            // 计算对角线长度

            let r = Math.sqrt(w*w + h*h);

            let wDiff = r - w, hDiff = r - h;

            // var fragment = document.createDocumentFragment();
            var canvasBox = util.createElement({name:"div",attr:{
                style:{
                    position:"relative",
                    width:"100%",
                    height:"100%"
                }
            }});
            var canvas = {};
            if(edit){
                let canvas_top = this.createCanvas("canvas_top",w,h);
                canvas_top.style.zIndex = 6;

                let canvas_preview = this.createCanvas("canvas_preview",w,h);
                canvas_preview.style.zIndex = 5;

                canvas.canvas_top = canvas_top;
                canvas.canvas_preview = canvas_preview;

                canvasBox.appendChild(canvas_top);
                canvasBox.appendChild(canvas_preview);
            }

            let canvas_shape = this.createCanvas("canvas_shape",w,h);
            canvas.canvas_shape = canvas_shape;
            canvas_shape.style.zIndex = 3;
            canvas_shape.style.opacity = 0.7;
            canvasBox.appendChild(canvas_shape);

            let canvas_global = this.createCanvas("canvas_global",w,h);
            canvas_global.style.zIndex = 2;

            let canvas_flag = this.createCanvas("canvas_flag",w,h);
            canvas_flag.style.zIndex = 4;
            canvas.canvas_flag = canvas_flag;
            canvasBox.appendChild(canvas_flag);

            canvasBox.appendChild(canvas_global);
            canvas.canvas_global = canvas_global;
            if(grid){
                let canvas_grid = this.createCanvas("canvas_grid",w,h);
                canvas_grid.style.zIndex = 1;

                canvasBox.appendChild(canvas_grid);
                canvas.canvas_grid = canvas_grid;
            }

            parentEle.appendChild(canvasBox);

            return canvas;
            
        },

        createCanvas(className,width,height){
            let canvas = util.createElement({name:"canvas",attr:{
                className:className,
                style:{
                    position:"absolute",
                    left:0,
                    right:0,
                    pointerEvents:"none"
                }
            }});
            canvas.width = width;
            canvas.height = height;
            return canvas;
        },

        resize(canvasObj,size){
            let canvasNames = ["canvas_top","canvas_preview","canvas_shape","canvas_grid","canvas_global"];
            canvasNames.forEach(canvasname=>{
                let canvas = canvasObj[canvasname];
                if(canvas){
                    canvas.width = size[0];
                    canvas.height = size[1];
                }
            });
        }
    }

    // 默认参数
    let drawDefParams = {
        //配置文件   
        imgStyleConfig:{
            pin:{
                color:{
                    t:"#b34141",
                    ts_t:"#990066",
                    ts_b:"#990066",
                    tp_t:"#CCCCFF",
                    tp_b:"#CCCCFF",
                    
                    i:"#99CCCC",
                    is_t:"#990066",
                    is_b:"#990066",
                    ip_t:"#CCCCFF",
                    ip_b:"#CCCCFF",
                    
                    b:"#336699",
                    bs_t:"#990066",
                    bs_b:"#990066",
                    bp_t:"#CCCCFF",
                    bp_b:"#CCCCFF",
                    
                    drill:"#CCCCCC",//过孔颜色
                    contour:"#99CCCC",   //pin描边颜色 
                }
            },
            layer:{
                st:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                sb:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                at:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                ab:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                sm_t:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                sm_b:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                et:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                eb:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                bt:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                bb:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                pt:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                pb:{
                    text:{
                        color_text:"black",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#1a2273",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },  
                },
                pinCoord:{
                    text:{
                        color_text:"#4DB8FE",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#c0c0c0",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },
                },
                pinCoordCount:{
                    text:{
                        color_text:"#fa4d4dd6",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#fa4d4dd6",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },
                },
                spacePinCoord:{
                    text:{
                        color_text:"#ADDBFC",//文字颜色
                        color_border:"red",//文字范围
                        typeface:"微软雅黑",//字体
                        text_size:"10",//字号
                    },
                    path:{
                        color_line:"#fa4d4dd6",//线颜色
                        line_width:1,//线宽
                    },
                    shape:{
                        color_fill:"green",//铜皮填充颜色
                        color_out:"#83b31e",//铜皮镂空部分颜色 
                        color_line:"while",//描边颜色
                        line_width:1,//线宽
                    },
                }
            },
            color_origin:"#a4bfa4",     //原点颜色
            typeface:"微软雅黑",            //全局字体 
            text_size:"20px",           //全局字号
            line_width:1,               //线宽
            txt_color:"black",
            
            highlight_color:"#ffbc00bd",  //强调的颜色
            highlight_scope:10,           //强调的范围
            grid_color:"#c0c0c0",       //格点颜色
        },
        /**
         * 记录图形信息
         */
        imgRecord :{
            pin_order:[],   //顺序整理后的pin
            pads:[],        //现有的pad
            pads_id:0,      //新加pad时的padid
            pins_id:0      //新加pin时的pinid
        },
        wind_layer:{
            all:false,
            st:true,
            sb:false,
            at:false,
            ab:false,
            pt:false,
            pb:false,
            et:false,
            eb:false,
            bt:false,
            bb:false,
            sm_t:false,
            sm_b:false,
        },
        wind_player:{
            all:false,
            tt:  true,
            ts_t:false,            //上层钢网
            tp_t:false,            //上层阻焊
            ts_b:false,            //下层钢网
            tp_b:false,            //下层阻焊
            ii:  false,             //中间层
            is_t:false,            //
            ip_t:false,            //
            is_b:false,            //
            ip_b:false,            //
            bb:  true,             //底层
            bs_t:false,            //
            bp_t:false,           //
            bs_b:false,            //
            bp_b:false, 
            inspect:false,       //检查顺序标志位
        },
        bright_img:{
            bright_all:false,    //双击选择全部种类pad标志位
            bright_all_id:null,  // 双击选择的padid
            bright_pad:[],  //需要锁定的pad高亮数组
            bright_pin:[],  //需要锁定的pin高亮数组
            
            bright_layer:[],  //需要锁定的层叠针对线、铜皮、字高亮数组
            bright_line:[],  //需要锁定的线高亮数组
            bright_text:[],  //需要锁定的字高亮数组
            bright_shape:[],  //需要锁定的铜皮高亮数组
            bright_f_o:[],  //需要锁定的铜皮填充或者开窗高亮数组
            _pin:  "", 
            _line: "",      
            _text: "", //click,all     
            _shape:"",     
        }
    };

    // 转回原始数据
    var toOriginMathods = {

        // 整合pin,将多个pin合并成一个pin
        toOriginPins(pins,isOrigin){
            let originPins = [];
            let statPin = {};
            pins.forEach(pin=>{
                if(pin.type == "pins"){
                    if(!statPin[pin.pinid]){
                        statPin[pin.pinid] = true;
                        let handlePin = {
                            x:pin.data.x,
                            y:pin.data.y,
                            rotate:pin.data.pRotate
                        }
                        if(isOrigin){
                            handlePin.pin_padid = pin.padid;
                            handlePin.pin_id = pin.pin_num;
                        }else{
                            handlePin.padid = pin.padid;
                            handlePin.pin_num = pin.pin_num;
                            handlePin.pinid = pin.pinid;
                        }
                        originPins.push(handlePin);
                    }
                }
            });
            return originPins;
        },

        // 将pad转换为原始数据格式
        toOriginPads(pads){
            var self = this;
            let padOutLayer = ["b","t","i"];
            let padInLayers = {
                b:["b","bs_t","bs_b","bp_t","bp_b"],
                t:["t","ts_t","ts_b","tp_t","tp_b"],
                i:["i","is_t","is_b","ip_t","ip_b"]
            };
            let layerFormTrans = {C:"CIRCLE",S:"RECTANGLE",OC:"OCTAGON",OV:"OBLONG"}
            let drillFormTrans = {C:"CIRCLE_DRILL",S:"RECTANGLE_SLOT",OC:"OCTAGON_DRILL",OV:"OVAL_SLOT"}
            let originPads = [];
            pads.forEach(pad=>{
                let originPad = {
                    name:pad.name,
                    id:pad.id,
                    drill:[],
                    name:pad.name || "ZDY_" + pad.id
                };
                padOutLayer.forEach(oLayer=>{
                    originPad[oLayer] = {};
                    padInLayers[oLayer].forEach(iLayer=>{
                        let layerData = transformOriginData(pad[iLayer]);
                        originPad[oLayer][iLayer] = layerData;
                    });
                });

                let drills = pad.drill || [];
                drills.forEach(drill=>{
                    let originDrill = {
                        hole: {
                            rotate: drill.rotate,
                            form: drillFormTrans[drill.form] || drill.form,
                            w: drill.w,
                            h: drill.h
                        },
                        keepout: "nil",
                        figure: {
                            w: drill.w,
                            name: "CROSS",
                            h: drill.h
                        },
                        diameter: drill.w,
                        offset: {
                            x: drill.skewing_x,
                            y: drill.skewing_y
                        },
                        plate: "nil",
                        tolerance: {
                            x: 0,
                            y: 0
                        },
                        uvia: "nil",
                        start_end_layer: {
                            end_layer: "ETCH/BOTTOM",
                            st_layer: "ETCH/TOP"
                        }
                    }
                    if(drill.form == "C"){
                        originDrill.figure.name = "Null";
                    }else if(drill.form == "OV"){
                        originDrill.figure.name = "OblongX";
                    }else if(drill.form == "S"){
                        originDrill.figure.name = "Rectangle";
                    }
                    originPad.drill.push(originDrill);
                });
                originPads.push(originPad);
            });

            function transformOriginData(layerData,isDrill){
                layerData = util.copyObject(layerData);
                if(layerData && layerData.form){
                    let form = layerData.form;
                    form = isDrill ? drillFormTrans[form] || form : layerFormTrans[form] || form;
                    if(form === "POLY"){
                        form = "PATH";
                        layerData = self.poly2Path(layerData);
                    }else if(form === "CS"){
                        form = "PATH";
                        layerData = self.cs2Path(layerData);
                    }else if(form === "OBLONG"){
                        if(layerData.w >= layerData.h){
                            form += "_X"
                        }else{
                            form += "_Y"
                        }
                    }else if(form === "RECTANGLE" && layerData.w == layerData.h){
                        form = "SQUARE";
                    }
                    layerData.form = form;
                }else{
                    layerData = {};
                }
                return layerData;
            }

            return originPads;
        },

        // 将cs转换成path
        cs2Path(cs){
            let r = cs.r;
            let originR = r;
            let w = cs.w;
            let h = cs.h;
            let x = 0, y=0;
            let arc_r = r < 0 ? "nil" : "t";
            r = Math.abs(r);
            var x1 = x - (w/2 - r),
                y1 = y+ h/2,
                x2 = x + (w/2 - r),
                y2 = y1,

                j1_x= x + w / 2 - r,   
                j1_y = y1 - r,   
                                
                x3 = x2 + r,      
                y3 = y2 - r,

                x4 = x3,

                y4 = y - (h/2 - r),

                j2_x = x4 - r,   
                j2_y = y4,   
                                
                x5 = x4 - r,        
                y5 = y4 - r,

                x6 = x - (w/2 - r),
                y6 = y5,

                j3_x = x6,
                j3_y = y6 + r,
                
                x7 = x6 - r,
                y7 = y6 + r,

                x8 = x7,
                y8 = y + (h/2 -r),

                j4_x = x8 + r,
                j4_y = y8;

            if(originR<0){
                j1_x = x + w / 2,   
                j1_y = y + h / 2,   
                j2_x = x + w / 2,   
                j2_y = y - h / 2,   
                j3_x = x - w / 2,
                j3_y = y - h / 2,
                j4_x = x - w / 2,
                j4_y = y + h / 2;
            }
            
            let path = [];
            path.push(this.point2Line([x1,y1],[x2,y2]));
            path.push(this.point2Arc([x2,y2],[x3,y3],[j1_x,j1_y],r,arc_r));
            path.push(this.point2Line([x3,y3],[x4,y4]));
            path.push(this.point2Arc([x4,y4],[x5,y5],[j2_x,j2_y],r,arc_r));
            path.push(this.point2Line([x5,y5],[x6,y6]));
            path.push(this.point2Arc([x6,y6],[x7,y7],[j3_x,j3_y],r,arc_r));
            path.push(this.point2Line([x7,y7],[x8,y8]));
            path.push(this.point2Arc([x8,y8],[x1,y1],[j4_x,j4_y],r,arc_r));
            let pathData = {
                form:"PATH",
                skewing_x:cs.skewing_x,
                skewing_y:cs.skewing_y,
                rotate:cs.rotate,
                path
            };
            return pathData;
        },

        // poly转换成path
        poly2Path(poly){
            let r = poly.r;
            let num = poly.num || 8;
            let rotate = poly.rotate;
            let points = [];

            var startX = r * Math.cos(2*Math.PI*0/num);//1
            var startY = r * Math.sin(2*Math.PI*0/num);//0
            if(poly%2==1){
                startX = r * Math.sin(2*Math.PI*0/num);//1
                startY = r * Math.cos(2*Math.PI*0/num);//0
                points.push([startX,startY]);
                for(var i = 1; i <= num; i++) {
                    var newX = r * Math.sin(2*Math.PI*i/num);
                    var newY = r * Math.cos(2*Math.PI*i/num);
                    points.push([newX,newY]);
                }
            }else{
                points.push([startX,startY]);
                for(var i = 1; i <= num; i++) {
                    var newX = r * Math.cos(2*Math.PI*i/num);
                    var newY = r * Math.sin(2*Math.PI*i/num);
                    points.push([newX,newY]);
                }
            }
            if(rotate){
                points = util.rotatePoints(points,[ox,oy],rotate);
            }
            let path = this.points2Lines(points);
            let pathData = {
                form:"PATH",
                skewing_x:poly.skewing_x,
                skewing_y:poly.skewing_y,
                rotate:poly.rotate,
                path
            };
            return pathData;
        },

        // 坐标点转成路径
        points2Lines(points){
            let lines = [];
            for(let i = 0, l = points.length;i < l;i++){
                let linePoint1 = points[i];
                let linePoint2 = i == l - 1 ? points[0] : points[i+1];
                let line = this.point2Line(linePoint1,linePoint2);
                lines.push(line);
            }
            return lines;
        },

        // point2Line 路径点转线
        point2Line(point1,point2,width){
            let line = {
                st_x:point1[0],
                st_y:point1[1],
                sp_x:point2[0],
                sp_y:point2[1],
                width:width || 0,
                name:"LINE",
                arc_r:"nil",
                o_x: 0,
                o_y: 0,
                r:0
            }
            return line;
        },

        // point2Arc 路径点转弧
        point2Arc(point1,point2,oPoint,r,dir,width){
            let arc = {
                st_x:point1[0],
                st_y:point1[1],
                sp_x:point2[0],
                sp_y:point2[1],
                width:width || 0,
                name:"ARC",
                arc_r:dir || "nil",
                o_x: oPoint[0],
                o_y: oPoint[1],
                r:r
            };
            return arc;
        },

        // 将图形进行分层
        imageForLayered(images){
            let smallToBig = {st:"ss",sb:"ss",at:"asm",ab:"asm",sm_t:"sm",sm_b:"sm",et:"e",eb:"e",bt:"b",bb:"b",pt:"p",pb:"p"};
            let imgData = {
                ss:{
                    st:{
                        path:[],
                        shapes:[],
                        texts:[]
                    },
                    sb:{
                        path:[],
                        shapes:[],
                        texts:[]
                    }
                },
                asm:{
                    at:{
                        path:[],
                        shapes:[],
                        texts:[]
                    },
                    ab:{
                        path:[],
                        shapes:[],
                        texts:[]
                    }
                },
                sm:{
                    sm_t:{
                        path:[],
                        shapes:[],
                        texts:[]
                    },
                    sm_b:{
                        path:[],
                        shapes:[],
                        texts:[]
                    }
                },
                e:{
                    et:{
                        path:[],
                        shapes:[],
                        texts:[]
                    },
                    eb:{
                        path:[],
                        shapes:[],
                        texts:[]
                    }
                },
                b:{
                    bt:{
                        path:[],
                        shapes:[],
                        texts:[]
                    },
                    bb:{
                        path:[],
                        shapes:[],
                        texts:[]
                    }
                },
                p:{
                    pt:{
                        path:[],
                        shapes:[],
                        texts:[]
                    },
                    pb:{
                        path:[],
                        shapes:[],
                        texts:[]
                    }
                },
            }
            images.forEach(img=>{
                let smallLayer = img.layer;
                let bigLayer = smallToBig[smallLayer];
                if(img.type === "shapes"){
                    var shapeData = {
                        fill:[],
                        outline:[]
                    }
                    imgData[bigLayer][smallLayer].shapes.push(shapeData)
                    if(img.make === "o"){
                        shapeData.outline = img.data;
                    }else{
                        shapeData.fill = img.data;
                    }
                }
                if(img.type === "path"){
                    let name = img.form.toUpperCase();
                    let data = img.data;
                    data.name = name;
                    if(name == "LINE" || name == "ARC"){
                        if(img.mark){
                            data.mark = true;
                        }
                        imgData[bigLayer][smallLayer].path.push(data);
                        return;
                    }
                    // 转换矩形
                    if(name == "S"){
                        let transLines = this.rect2Path(data);
                        transLines.forEach(line=>{
                            line.width = data.width;
                        });
                        [].push.apply(imgData[bigLayer][smallLayer].path,transLines);
                        return;
                    }
                    if(name == "OV"){
                        let transLines = this.ov2Path(data);
                        console.log(transLines);
                        [].push.apply(imgData[bigLayer][smallLayer].path,transLines);
                        return;
                    }
                    if(name == "OC"){
                        let transLines = this.poly2Path(data).path;
                        [].push.apply(imgData[bigLayer][smallLayer].path,transLines);
                        return;
                    }
                }
                if(img.type === "texts"){
                    imgData[bigLayer][smallLayer].texts.push(img.data);
                }
            });
            return imgData;
        },

        // 矩形转路径
        rect2Path(rectData){
            let ox = rectData.x,
                oy = rectData.y,
                w = rectData.w,
                h = rectData.h,
                rotate = rectData.rotate;
            let points = [
                [ox-w/2,oy+h/2],
                [ox+w/2,oy+h/2],
                [ox+w/2,oy-h/2],
                [ox-w/2,oy-h/2]
            ];
            if(rotate){
                points = util.rotatePoints(points,[ox,oy],rotate);
            }
            return this.points2Lines(points);
        },

        // 椭圆转路径
        ov2Path(ovData){
            let w = ovData.w,
                h = ovData.h,
                ox = ovData.x,
                oy = ovData.y,
                width = ovData.width,
                rotate = ovData.rotate;
            let lines = [];
            let points = [];
            let centerPoints = [];
            let r = 0;
            if(w > h){
                r = h/2;
                centerPoints = [
                    [ox + w/2 - r, oy],
                    [ox - w/2 + r, oy]
                ];
                points = [
                    [ox - w/2 + r, oy + r],
                    [ox + w/2 - r, oy + r],
                    [ox + w/2 - r, oy - r],
                    [ox - w/2 + r, oy - r]
                ];
            }else if(w < h){
                r = w / 2;
                centerPoints = [
                    [ox, oy - h/2 + r],
                    [ox, oy + h/2 - r]
                ];
                points = [
                    [ox + r, oy + h/2 - r],
                    [ox + r, oy - h/2 + r],
                    [ox - r, oy - h/2 + r],
                    [ox - r, oy + h/2 - r]
                ];
            }else{
                r = w / 2;
                centerPoints = [
                    [ox,oy]
                ];
                points = [
                    [ox + r, oy],
                    [ox - r, oy]
                ];
            }
            
            if(rotate){
                points = util.rotatePoints(points,[ox,oy],rotate);
                centerPoints = util.rotatePoints(centerPoints,[ox,oy],rotate);
            }
            if(points.length === 4){
                lines.push(this.point2Line(points[0],points[1],width));
                lines.push(this.point2Arc(points[1],points[2],centerPoints[0],r,"t",width));
                lines.push(this.point2Line(points[2],points[3],width));
                lines.push(this.point2Arc(points[3],points[0],centerPoints[1],r,"t",width));
            }else{
                lines.push(this.point2Arc(points[0],points[1],centerPoints[0],r,"t",width));
                lines.push(this.point2Arc(points[1],points[0],centerPoints[0],r,"t",width));
            }
            return lines;
        },

        // 转换成下载的数据
        transformOriginData(imgDataTable,handlePads){
            let pins = imgDataTable.filter(img=>img.type==="pins");
            let images = imgDataTable.filter(img=>img.type!=="pins");

            let originPins = this.toOriginPins(pins,true);
            let originPads = this.toOriginPads(handlePads);
            let imgData = this.imageForLayered(images);
            imgData = {
                ...imgData,
                pads:originPads,
                pins:originPins,
                header:{}
            };
            return imgData;
        },
    }

    // 处理图形所用到的工具
    var handleUtil = {
        // 对封装数据进行格式化，传入值有误则生成一个空白的封装
        formatEncaData(encaData){
            if(!encaData || util.getRawType(encaData) !== "Object"){
                encaData = {
                    units:"mm",
                    img_data:{}
                };
            }
            if(!encaData.units){
                encaData.units = "mm";
            }
            if(!encaData.img_data || util.getRawType(encaData) !== "Object"){
                encaData.img_data = {};
            }
            return encaData;
        },

        //整合数据 (会改变格点设置)
        init_basics:function init_basics(unit_lock){
            unit_lock = unit_lock || "mm";
            
            var basics = {};
            //设置格点
            if(unit_lock=="mm"){
                basics={//基础配置栏
                    zoom:1,
                    init_zoom:1,
                    units:"mm",
                    unitsorg:"mm",    //初始单位
                    gridx:0.5,
                    gridy:0.5,
                    gridorgx:0,
                    gridorgy:0,
                    gridacalx:0,    //当前实际格点
                    gridacaly:0,    
                    gridzoomx:0,    //当前实际格点*缩放
                    gridzoomy:0,
                };
            }
            else if(unit_lock=="mil"||unit_lock=="mils"){
                basics={//基础配置栏
                    zoom:1,
                    init_zoom:1,
                    units:"mils",
                    unitsorg:"mils",    //初始单位
                    gridx:39.37,
                    gridy:39.37,
                    gridorgx:0,
                    gridorgy:0,
                    gridacalx:0,    //当前实际格点
                    gridacaly:0,    
                    gridzoomx:0,    //当前实际格点*缩放
                    gridzoomy:0,
                };
            }
            return basics;
        },

        // 计算范围
        computed_range(img_run,basics,topbot_layer){
            var unitsinfo=basics;
            var layermode=topbot_layer,
                g=unitsinfo.gridacalx,    //实际单个格点值
                f=unitsinfo.gridx;//理论单个格点值
            
            var pins=img_run.pins,  //引脚
                pads=img_run.pads;
            var ss_lines = [];
            var asm_lins = [];
            if(layermode=="top"){
                if(img_run.ss){
                    ss_lines=img_run.ss.st.path instanceof Array?img_run.ss.st.path:[],  //丝印层
                    asm_lins=img_run.asm.at.path instanceof Array?img_run.asm.at.path:[];  //装配层
                }
            }
                    
            var pin_x_all=[],
                pin_y_all=[],
                ss_line_x_all=[],
                ss_line_y_all=[],
                asm_line_x_all=[],
                asm_line_y_all=[];
            
            if(pins.length==1){
                pads.forEach(function(p_pin){
                    let path={},path_name="";
                    path_name=p_pin.t.t.form;
                    if(path_name=="path"){
                        path=p_pin.t.t.path;
                        path.forEach(function(line){
                            asm_line_x_all[asm_line_x_all.length]=line.st_x||0;
                            asm_line_y_all[asm_line_y_all.length]=line.st_y/f*g||0;
                            asm_line_x_all[asm_line_x_all.length]=line.sp_x/f*g||0;
                            asm_line_y_all[asm_line_y_all.length]=line.sp_y/f*g||0;
                        });
                    }
                    
                });
            }else{
                pins.forEach(function(pin,a){//获取pin的x，y值
                    pin_x_all[a]=pin.x/f*g;
                    pin_y_all[a]=pin.y/f*g;
                });
            }
            var st_x=0,
                st_y=0,
                sp_x=0,
                sp_y=0;
            ss_lines.forEach(function(ss_line,b){//获取丝印层线的x,y值
                //如果外框是圆形
                if(ss_line.name=="arc"&&(ss_line.st_x==ss_line.sp_x)&&(ss_line.sp_y==ss_line.st_y)){
                    st_x=ss_line.st_x/f*g||0;
                    st_y=(ss_line.st_y-ss_line.r)/f*g||0;
                    sp_x=(ss_line.sp_x-2*ss_line.r)/f*g||0;
                    sp_y=(ss_line.sp_y+ss_line.r)/f*g||0;
                }else{
                    st_x=ss_line.st_x/f*g||0;
                    st_y=ss_line.st_y/f*g||0;
                    sp_x=ss_line.sp_x/f*g||0;
                    sp_y=ss_line.sp_y/f*g||0;
                }
                ss_line_x_all[ss_line_x_all.length]=st_x/f*g;
                ss_line_y_all[ss_line_y_all.length]=st_y/f*g;
                ss_line_x_all[ss_line_x_all.length]=sp_x/f*g;
                ss_line_y_all[ss_line_y_all.length]=sp_y/f*g;
            });    
            asm_lins.forEach(function(asm_line,c){//装配层线的x，y值
                //如果外框是圆形
                if(asm_line.name=="arc"){
                    st_x=asm_line.st_x/f*g||0;
                    st_y=(asm_line.st_y-asm_line.r   )/f*g||0;
                    sp_x=(asm_line.sp_x-2*asm_line.r )/f*g||0;
                    sp_y=(asm_line.sp_y+asm_line.r   )/f*g||0;
                }else{
                    st_x=asm_line.st_x/f*g||0;
                    st_y=asm_line.st_y/f*g||0;
                    sp_x=asm_line.sp_x/f*g||0;
                    sp_y=asm_line.sp_y/f*g||0;
                }
                asm_line_x_all[asm_line_x_all.length]=asm_line.st_x/f*g||0;
                asm_line_y_all[asm_line_y_all.length]=asm_line.st_y/f*g||0;
                asm_line_x_all[asm_line_x_all.length]=asm_line.sp_x/f*g||0;
                asm_line_y_all[asm_line_y_all.length]=asm_line.sp_y/f*g||0;
            });
            var max_ss_x=Math.max.apply(0, ss_line_x_all),//丝印层x轴最大坐标
                max_ss_y=Math.max.apply(0, ss_line_y_all),//丝印层y轴最大坐标
                min_ss_x=Math.min.apply(0, ss_line_x_all),//丝印层x轴最小坐标
                min_ss_y=Math.min.apply(0, ss_line_y_all);//丝印层y轴最小坐标
            var max_asm_x=Math.max.apply(0, asm_line_x_all),//装配层x轴最大坐标
                max_asm_y=Math.max.apply(0, asm_line_y_all),//装配层y轴最大坐标
                min_asm_x=Math.min.apply(0, asm_line_x_all),//装配层x轴最小坐标
                min_asm_y=Math.min.apply(0, asm_line_y_all);//装配层y轴最小坐标
        
            var max_p_x=Math.max.apply(0, pin_x_all),//x轴最大坐标
                max_p_y=Math.max.apply(0, pin_y_all),//y轴最大坐标
                min_p_x=Math.min.apply(0, pin_x_all),//x轴最小坐标
                min_p_y=Math.min.apply(0, pin_y_all);//y轴最小坐标
            
            //检测pin是否在框线外部
            var sum_x=pin_x_all.concat(ss_line_x_all);//引脚与丝印层
            var sum_y=pin_y_all.concat(ss_line_y_all);
            
            var sum_max_x=Math.max.apply(0, sum_x),//x轴最大坐标
                sum_max_y=Math.max.apply(0, sum_y),//y轴最大坐标
                sum_min_x=Math.min.apply(0, sum_x),//x轴最小坐标
                sum_min_y=Math.min.apply(0, sum_y);//y轴最小坐标
            
            var p_w=max_p_x/1-min_p_x/1,
                p_h=max_p_y/1-min_p_y/1,
                s_w=max_ss_x/1-min_ss_x/1,
                s_h=max_ss_y/1-min_ss_y/1,
                a_w=max_asm_x/1-min_asm_x/1,
                a_h=max_asm_y/1-min_asm_y/1,
                sum_w=sum_max_x/1-sum_min_x/1,
                sum_h=sum_max_y/1-sum_min_y/1;
            var img_w=0,                        //图形宽度
                img_h=0;                        //图形高度
            
            var x_left=0,                       //x左上角坐标
                y_left=0;                       //y左上角坐标
            //判断是pin or ss or asm的长宽最大Math.abs：取绝对值
            var img_area_all=[Math.abs(p_w)*Math.abs(p_h),Math.abs(s_w)*Math.abs(s_h),Math.abs(a_w)*Math.abs(a_h),Math.abs(sum_w)*Math.abs(sum_h)];
            var img_area=img_area_all[0],
                img_area_type=0;
            for(var img_a=0;img_a<img_area_all.length;img_a++){
                if(img_area_all[img_a]>img_area){
                    img_area=img_area_all[img_a];
                    img_area_type=img_a;
                }
            }
            var img_xyz_mode='';
            //图形长和宽
            if(img_area_type==0){//pin图形最大
                img_w=p_w;
                img_h=p_h;
                x_left=min_p_x;
                y_left=min_p_y;
                img_xyz_mode="pin";
            }else if(img_area_type==1){//丝印层图形最大
                img_w=s_w;
                img_h=s_h;
                x_left=min_ss_x;
                y_left=min_ss_y;
                img_xyz_mode="ss";
            }else if(img_area_type==2){  //装配层图形最大
                img_w=a_w;
                img_h=a_h;
                x_left=min_asm_x;
                y_left=min_asm_y;
                img_xyz_mode="asm";
            }else{
                img_w=sum_w;
                img_h=sum_h;
                img_xyz_mode="sum"; 
            }
            return {
                img_w,
                img_h,
                x_left,
                y_left,
                img_xyz_mode,
                max_ss_x,
                max_ss_y,
                min_ss_x,
                min_ss_y,
                max_asm_x,
                max_asm_y,
                min_asm_x,
                min_asm_y
            }
        },

        // 计算缩放倍速
        computed_scale(rangeObj,canvasSize){
        /*  origin_x=（画布长-w）/2+x_min;
        /*  origin_y=（画布宽-h）/2+y_min;
            pin的最大间距：
            丝印层最大线长：
            装配层最大线长：
            以x轴最大定w，y轴最大定h；
            
        */

            var canvas_w=canvasSize[0],   //画布高度
                canvas_h=canvasSize[1];   //画布高度 

            //this.data.multiplier="min";//缩放标识max放大。min缩小
            var w_zoom=1,//x轴缩放倍数
                h_zoom=1;//y轴缩放倍数
            var boundary=40;
            //计算缩放倍数
            if(rangeObj.img_w<(canvas_w-boundary)){//图形最大宽度小于画布宽度时，判断是否放大
                for(var d=1;d<100;d++){
                    if(rangeObj.img_w*d>=(canvas_w-boundary)){
                        w_zoom=d-1;
                        break;
                    }
                    if(d==99){//达到最大时取最大值
                        w_zoom=d;
                        break;
                    }
                }
            }else{//图形最大宽度小于或等于画布宽度时，判断缩小
                for(var f=1;f<100;f++){
                    if((rangeObj.img_w/f)<=(canvas_w-boundary)){
                        w_zoom=-(f+1);
                        break;
                    }
                    if(f==99&&(rangeObj.img_w*d>=(canvas_w-boundary))){//达到最大时取最大值
                        w_zoom=-(f);
                        break;
                    }
                }
            }
            if(rangeObj.img_h<(canvas_h-boundary)){//图形最大高度小于画布高度时，判断是否放大
                for(var e=1;e<100;e++){
                    if(rangeObj.img_h*e>=(canvas_h-boundary)){
                        h_zoom=e-1;
                        break;
                    }
                    if(e==99&&(rangeObj.img_h*e<=(canvas_h-boundary))){//达到最大时取最大值
                        h_zoom=e;
                        break;
                    }
                }
            }else{//图形最大高度小于或等于画布高度时，判断缩小
                for(var g=1;g<100;g++){
                    if((rangeObj.img_h/g)<(canvas_h-boundary)){
                        h_zoom=-(g+1);
                        break;
                    }
                    if(g==99&&(rangeObj.img_h*g>=(canvas_h-boundary))){//达到最大时取最大值
                        h_zoom=-g;
                        break;
                    }
                }
            }
            var zoom=[],
                d_d=0;
            //整合缩放
            if(h_zoom<0&&w_zoom<0){//缩小
                zoom=[w_zoom,h_zoom];
                d_d=Math.max.apply(0, zoom.toString().split(',').map(Number));//最大放大倍数
            }else if(h_zoom>0&&w_zoom>0){//放大
                zoom=[w_zoom,h_zoom];
                d_d=Math.min.apply(0, zoom.toString().split(',').map(Number));//最小缩放倍数
            }else{//某一方向缩小就以缩小方向为整体缩放
                if(h_zoom<0){
                    d_d=h_zoom;
                }else{
                    d_d=w_zoom;
                }
            }
            if(d_d==1||d_d==-1){
                d_d=d_d/2;
            }
            //计算原点
            if(d_d<0){//负数为除
                d_d=1/Math.abs(d_d);//绝对值
            }
            return d_d;
        },

        //整理顺序
        pin_order:function pin_order(pins){
            if(!pins){
                return {};
            }
            let pin_all=pins,
                text_en=/^[a-zA-Z]+$/,          //字母检测
                text_zn=/^[0-9]*[1-9][0-9]*$/;//数字检测
            if(!pin_all||!pin_all.length||pin_all.length==0){
                return;
            }
            let all=[],
                en_pin=[],  //字母
                num_pin=[],  //数字
                en_num=[],  //数字加字母
                zn_pin=[];  //无标识
            //分类
            pin_all.forEach(function(a_d){
                if(text_en.test(a_d.id)){
                    en_pin[en_pin.length]=a_d;
                }else if(text_zn.test(a_d.id)){
                    num_pin[num_pin.length]=a_d;
                }else{
                    if(a_d.id==""||a_d.id=="机械孔"||a_d.id==null){
                        zn_pin[zn_pin.length]=a_d;
                    }else{
                        en_num[en_num.length]=a_d;
                    }
                }
            });
            //排序
            //对纯数字的排序1-100
            num_pin=num_pin.sort(function(j, k){return j.id - k.id});
            //对纯字母的排序a-z
            en_pin=en_pin.sort((a, b) => a.id.charCodeAt(0) - b.id.charCodeAt(0));
            let new_ennum=[];
            //对字母加数字的排序(没做完)
            en_num.forEach(function(a_d){//原始数组
                let name_r=a_d.id;
                new_ennum.forEach(function(b_d){
                    let name_l=b_d.id,
                        lock_max=false;
                        
                    //对name抽出单个字符检测
                    for(var c=1;c<name_r.length;c++){
                        let r_en=name_r.slice(0,c),
                            r_id=name_r.slice(c,t_num);
                            l_en=name_l.slice(0,c),
                            l_id=name_l.slice(c,t_num);
                        //检测字母  
                        let en_all=[r_en,len];
                        en_all=en_all.sort();
                    }
                    if(lock_max){
                        
                    }
                    
                });   
            });
            
            //整合
            num_pin.forEach(function(w){
                all[all.length]=w;
            });
            en_pin.forEach(function(w){
                all[all.length]=w;
            });
            en_num.forEach(function(w){
                all[all.length]=w;
            });
            return all;
        },

        // 转换成绘图数据
        handlerImg(imgData){
            let imgList = [];
            let imgIdSum = 0;
            if(isEmpty(imgData)){
                return imgList;
            }
            let bigLayerList = ["ss","asm","sm","e","b","p"];
            let layerList = {ss:["st","sb"],asm:["at","ab"],sm:["sm_t","sm_b"],e:["et","eb"],b:["bt","bb"],p:["pt","pb"]};
            bigLayerList.forEach(function(bigLayer){
                let smallLayerList = layerList[bigLayer];
                smallLayerList.forEach(function(smallLayer){
                    if(!imgData[bigLayer]){
                        return;
                    }
                    let layerData = imgData[bigLayer][smallLayer];
                    imgList = imgList.concat(handlerLayer(smallLayer,layerData));
                });
            });
            imgList = imgList.concat(pinsHandler(imgData.pads,imgData.pins))
            return imgList;

            function handlerLayer(layer,layerData){
                let layerImgList = [];
                let shapeList = ["path","texts","shapes"];
                let nameConversion = {CIRCLE:"C",CIRCLE_DRILL:"C",SQUARE:"S",RECTANGLE:"S",RECTANGLE_DRILL:"S",SQUARE_DRILL:"S",OCTAGON:"OC",HOLE_OCTAGON:"OC",OCTAGON_DRILL:"OC",OBLONG_Y:"OV",OVAL:"OV",OBLONG_X:"OV",HOLE_OVAL:"OV",OVAL_DRILL:"OV",OVAL_SLOT:"OV"}
                shapeList.forEach(function(shapeName){
                    let shapeList = layerData[shapeName] || [];
                    if(shapeName === "shapes"){
                        if(shapeList.length){
                            layerImgList = layerImgList.concat(shapesHandler(shapeList,layer));
                        }
                    }else{
                        if(shapeList.length){
                            for(let i = 0,l = shapeList.length; i < l; i++){
                                let imgItem = {
                                    id:++imgIdSum,
                                    layer,
                                    type:shapeName,
                                    form:nameConversion[shapeList[i].name] || shapeList[i].name.toUpperCase(),
                                    data:shapeList[i]
                                }
                                layerImgList.push(imgItem);
                            }
                        }
                    }
                });
            
                function shapesHandler(shapeList,layer){
                    let imgList = [];
                    let copperSheetType = ["outline","fill"];
                    shapeList.forEach(shape=>{
                        copperSheetType.forEach(type=>{
                            let typeData =  shape[type] || [];
                            if(typeData.length){
                                let imgItem = {
                                    id:++imgIdSum,
                                    layer,
                                    form:"PATH",
                                    type:"shapes",
                                    make:type==="fill"?"f":"o",
                                    data:typeData
                                }
                                imgList.push(imgItem);
                            }
                        });
                    });
                    return imgList;
                }
                return layerImgList;
            }
            
            /**
             * 
             * @param {encaData['img_data']['pins']} pins 
             * @param {encaData['img_data']['pads']} pads 
             * @returns 
             */
            function pinsHandler(pads,pins){
                if(!pins.length){
                    return [];
                }
                let nameConversion = {CIRCLE:"C",CIRCLE_DRILL:"C",SQUARE:"S",RECTANGLE:"S",RECTANGLE_DRILL:"S",SQUARE_DRILL:"S",OCTAGON:"OC",HOLE_OCTAGON:"OC",OCTAGON_DRILL:"OC",OBLONG_Y:"OV",OVAL:"OV",OBLONG_X:"OV",HOLE_OVAL:"OV",OVAL_DRILL:"OV",OVAL_SLOT:"OV"}
                let padBigLayer = ["b","t","i"];
                let padSmallLayer = {b:["b","bs_t","bs_b","bp_t","bp_b"],t:["t","ts_t","ts_b","tp_t","tp_b"],i:["i","is_t","is_b","ip_t","ip_b"]};
                let imgList = [];
                pins.forEach(function(pin,index){
                    let pad = pads.find(function(pad){
                        return pad.id === pin.pin_padid;
                    });
                    let h_type,p_type;
                    if(pad.drill && pad.drill.length>0){
                        h_type=true;
                    }else{
                        h_type=false;
                    }
                    if(pad.t.t.form){
                        p_type=true;
                    }else if(pad.b.b.form){
                        p_type=true;
                    }else{
                        p_type=false;
                    }
                    let kind = "";
                    if(h_type&&p_type){
                        kind="via";
                    }else if(!h_type&&p_type){
                        kind="smt";
                    }else if(h_type&&!p_type){
                        kind="hole";
                    }
                    let pinItem = {
                        padid:pin.pin_padid,
                        pinid:index + 1,
                        pin_num:pin.pin_id,
                        type:"pins",
                        kind
                    };
                    padBigLayer.forEach(function(bigLayer){
                        padSmallLayer[bigLayer].forEach(function(smallLayer){
                            let padLayerData = pad[bigLayer][smallLayer];
                            if(!padLayerData.form){
                                return;
                            }
                            let form = padLayerData.form.toUpperCase();
                            padLayerData.form = nameConversion[form] ?nameConversion[form] : form;
                            if((padLayerData.form === "OC" || padLayerData.form === "C") && !padLayerData.r){
                                padLayerData.r = padLayerData.w/2;
                            }
                            let imgItem = JSON.parse(JSON.stringify(pinItem));
                            imgItem.id = ++imgIdSum;
                            imgItem.pin_layer = smallLayer;
                            imgItem.data = JSON.parse(JSON.stringify(padLayerData));
                            imgItem.data.x = pin.x;
                            imgItem.data.y = pin.y;
                            imgItem.data.pRotate = pin.rotate || 0;
                            
                            imgList.push(imgItem);
                        });
                    });
                    if(pad.drill instanceof Array){
                        pad.drill.forEach(drill=>{
                            let imgItem = JSON.parse(JSON.stringify(pinItem));
                            imgItem.rawData = JSON.parse(JSON.stringify(drill));
                            let hole = imgItem.rawData.hole;
                            imgItem.id = ++imgIdSum;
                            imgItem.pin_layer = "drill";
                            imgItem.data = {};
                            imgItem.data.x = pin.x;
                            imgItem.data.y = pin.y;
                            imgItem.data.pRotate = pin.rotate || 0;
                            imgItem.data.rotate = hole.rotate || 0;
                            imgItem.data.form = hole.form;

                            let form = imgItem.data.form.toUpperCase();
                            imgItem.data.form = nameConversion[form] ? nameConversion[form] : form;

                            if(imgItem.data.form === "C"){
                                imgItem.data.w = imgItem.rawData.diameter;
                                imgItem.data.h = imgItem.rawData.diameter;
                                imgItem.data.r = imgItem.rawData.diameter/2;
                            }else{
                                imgItem.data.w = hole.w;
                                imgItem.data.h = hole.h;
                            }
                            if(hole.r){
                                imgItem.data.r = hole.r;
                            }
                            imgItem.data.skewing_x = imgItem.rawData.offset.x;
                            imgItem.data.skewing_y = imgItem.rawData.offset.y;
                            imgList.push(imgItem);
                        });
                    }
                });
                return imgList;
            }
        },
        
        // 图形拆分
        imageSplit(imgList){
            imgList = util.copyObject(imgList,function(index,data){
                return util.copyObject(data,(attr,value)=>{
                    if(attr == "bindFigure"){
                        return undefined;
                    }
                    return value;
                });
            });
            let pins = [];
            let paths=  [];
            let shapes= [];
            let texts=  [];
            if(imgList && imgList.forEach){
                imgList.forEach(item=>{
                    if(item.type=="shapes"){
                        shapes.push(item);
                    }else if(item.type=="path"){
                        paths.push(item);
                    }else if(item.type=="texts"){
                        texts.push(item);
                    }else{
                        pins.push(item);
                    }
                });
                shapes.sort(function(s1,s2){
                    if(s1.make === s2.make){
                        return 0;
                    }else{
                        if(s1.make === "o"){
                            return 1;
                        }else{
                            return -1;
                        }
                    }
                });
                let pinPriority = {b:5,bs_t:3,bs_b:1,bp_t:4,bp_b:2,t:15,ts_t:13,ts_b:11,tp_t:14,tp_b:12,i:10,is_t:8,is_b:6,ip_t:9,ip_b:7,drill:16}
                //"b","bs_t","bs_b","bp_t","bp_b","t","ts_t","ts_b","tp_t","tp_b","i","is_t","is_b","ip_t","ip_b","drill"
                pins.sort(function(p1,p2){
                    return pinPriority[p1.pin_layer] - pinPriority[p2.pin_layer];
                });
            }
            
            return {
                pins,
                paths,
                shapes,
                texts
            };
        },

        // 处理pad
        handlerPad(pads){
            let handlePads = [];
            if(!pads){
                return handlePads;
            }
            let padBigLayer = ["b","t","i"];
            let padSmallLayer = {b:["b","bs_t","bs_b","bp_t","bp_b"],t:["t","ts_t","ts_b","tp_t","tp_b"],i:["i","is_t","is_b","ip_t","ip_b"]};
            let nameConversion = {CIRCLE:"C",CIRCLE_DRILL:"C",SQUARE:"S",RECTANGLE:"S",RECTANGLE_DRILL:"S",SQUARE_DRILL:"S",OCTAGON:"OC",HOLE_OCTAGON:"OC",OCTAGON_DRILL:"OC",OBLONG_Y:"OV",OVAL:"OV",OBLONG_X:"OV",HOLE_OVAL:"OV",OVAL_DRILL:"OV",OVAL_SLOT:"OV"}
            pads.forEach(originPad=>{
                let h_type,p_type;
                if(originPad.drill && originPad.drill.length>0){
                    h_type=true;
                }else{
                    h_type=false;
                }
                if(originPad.t.t.form){
                    p_type=true;
                }else if(originPad.b.b.form){
                    p_type=true;
                }else{
                    p_type=false;
                }
                let kind = "";
                if(h_type&&p_type){
                    kind="via";
                }else if(!h_type&&p_type){
                    kind="smt";
                }else if(h_type&&!p_type){
                    kind="hole";
                }
                let handlePad = {};
                handlePad.name = originPad.name;
                handlePad.id = originPad.id;
                padBigLayer.forEach(bigLayer=>{
                    padSmallLayer[bigLayer].forEach(smallLayer=>{
                        handlePad[smallLayer] = util.copyObject(originPad[bigLayer][smallLayer]);
                        if((handlePad[smallLayer].form === "OC" || handlePad[smallLayer].form === "C") && !handlePad[smallLayer].r){
                            handlePad[smallLayer].r = handlePad[smallLayer].w/2;
                        }
                    });
                });
                let handleDrills = [];
                originPad.drill && originPad.drill.forEach(drill=>{
                    drill = JSON.parse(JSON.stringify(drill));
                    let hole = drill.hole;
                    let form = hole.form.toUpperCase();
                    let handleDrill = {
                        pin_layer:"drill",
                        rotate:hole.rotate || 0,
                        form:nameConversion[form] || form,
                        skewing_x:drill.offset.x,
                        skewing_y:drill.offset.y
                    };
                    if(handleDrill.form === "C"){
                        handleDrill.w = drill.diameter;
                        handleDrill.h = drill.diameter;
                        handleDrill.r = handleDrill.w / 2;
                    }else{
                        handleDrill.w = hole.w;
                        handleDrill.h = hole.h;
                    }
                    if(hole.r){
                        handleDrill.r = hole.r;
                    }
                    handleDrills.push(handleDrill);
                });
                handlePad.drill = handleDrills;
                handlePad.kind = kind;
                handlePads.push(handlePad);
            });
            return handlePads;
            
        },

        // 合并pad和pin
        handlerPinDraw(pinList,padList){
            pinList = util.copyObject(pinList);
            padList = util.copyObject(padList);
            // console.log(pinList,padList)
            let handlerPins = [];
            
            let padSmallLayer = ["b","bs_t","bs_b","bp_t","bp_b","t","ts_t","ts_b","tp_t","tp_b","i","is_t","is_b","ip_t","ip_b","drill"];
            pinList.forEach(pin=>{
                let pad = padList.find(pad=>pad.id == pin.padid);
                padSmallLayer.forEach(pad_layer=>{
                    if(pad_layer !== "drill"){
                        let handlePin = {};
                        let pad_layer_data = util.copyObject(pad[pad_layer]);
                        if(!pad_layer_data || !pad_layer_data.form){
                            return;
                        }
                        handlePin = pinAndPad(pin,pad_layer_data);
                        handlePin.padid = pad.id;
                        handlePin.kind = pad.kind;
                        handlePin.pin_layer = pad_layer;
                        handlerPins.push(handlePin);
                    }else{
                        if(pad.drill && pad.drill.length){
                            pad.drill.forEach(drill=>{
                                let handlePin = pinAndPad(pin,util.copyObject(drill));
                                handlePin.padid = pad.id;
                                handlePin.kind = pad.kind;
                                handlePin.pin_layer = pad_layer;
                                handlerPins.push(handlePin);
                            });
                        }
                    }
                });
            });

            function pinAndPad(pin,padData){
                let handlePin = {};
                handlePin.data = padData;
                handlePin.data.x = pin.x;
                handlePin.data.y = pin.y;
                handlePin.type = "pins";
                handlePin.pin_num = pin.pin_num;
                handlePin.data.pRotate = pin.rotate;
                handlePin.pinid = pin.pinid;
                handlePin.id = pin.id;
                handlePin.isPreview = false;
                return handlePin;
            }
            return handlerPins;
        },

        // 更改图形原点
        changeEncaOrigin(imageList,offset){
            imageList = imageList.map(img=>{
                if(img.type === "pins"){
                    img.data.x -= offset.x;
                    img.data.y -= offset.y;
                    return img;
                }
                let form = img.form.toUpperCase();
                if(form === "PATH"){
                    img.data = img.data.map(line=>{
                        let name = line.name.toUpperCase();
                        if(name == "LINE"){
                            return changeLineOrigin(line,offset);
                        }
                        if(name == "ARC"){
                            return changeArcOrigin(line,offset)
                        }
                        return changeRectOrigin(line,offset)
                    });
                    return img;
                }
                if(form === "LINE"){
                    img.data = changeLineOrigin(img.data,offset);
                    return img;
                }
                if(form === "ARC"){
                    img.data = changeArcOrigin(img.data,offset);
                    return img;
                }
                img.data = changeRectOrigin(img.data,offset);
                return img;
            });

            return imageList;

            function changeLineOrigin(line,offset){
                let cLine = util.copyObject(line);
                cLine.st_x -= offset.x;
                cLine.st_y -= offset.y;
                cLine.sp_x -= offset.x;
                cLine.sp_y -= offset.y;
                return cLine;
            }

            function changeArcOrigin(line,offset){
                let cLine = util.copyObject(line);
                cLine.st_x -= offset.x;
                cLine.st_y -= offset.y;
                cLine.sp_x -= offset.x;
                cLine.sp_y -= offset.y;
                cLine.o_x -= offset.x;
                cLine.o_y -= offset.y;
                return cLine;
            }

            function changeRectOrigin(rect,offset){
                let cRect = util.copyObject(rect);
                cRect.x -= offset.x;
                cRect.y -= offset.y;
                return cRect;
            }
        },

        // 计算字体的宽高
        computedTextSize(text,textblock){
            if(typeof text != "string"){
                return;
            }
            let size = text.length;
            return {
                textwidth:textblock * size / 2,
                textheight:textblock
            }
        },

        // 移动图形
        moveImages(imgList,offset){
            imgList.forEach(img=>{
                if(img.type == "pins"){
                    img.data.x += offset.x;
                    img.data.y += offset.y;
                }
                if(img.type == "path"){
                    if(img.form == "ARC" || img.form == "LINE"){
                        img.data.st_x += offset.x; 
                        img.data.st_y += offset.y; 
                        img.data.sp_x += offset.x; 
                        img.data.sp_y += offset.y;
                        if(img.form == "ARC"){
                            img.data.o_x += offset.x; 
                            img.data.o_y += offset.y;
                        }
                    }
                    if(img.form == "S" || img.form == "OC" || img.form == "OV"){
                        img.data.x += offset.x;
                        img.data.y += offset.y;
                    }
                }
                if(img.type == "texts"){
                    img.data.x += offset.x;
                    img.data.y += offset.y;
                }
            });
            return imgList;
        },

        // 获取封装的正中心坐标
        getEncaRange:function(data){
            if(data==null||!data || !data.ss){
                return {
                    x:[
                        0,0
                    ],
                    y:[
                        0,0
                    ]
                };
            }
            /*  origin_x=（画布长-w）/2+x_min;
            /*  origin_y=（画布宽-h）/2+y_min;
                pin的最大间距：
                丝印层最大线长：
                装配层最大线长：
                以x轴最大定w，y轴最大定h；
                
            */
            var pins=data.pins,         //引脚
                pads=data.pads;

            var ss_lines = [],asm_lins = [];
            if(data.ss){
                ss_lines=data.ss.st.path instanceof Array?data.ss.st.path:[],  //丝印层
                asm_lins=data.asm.at.path instanceof Array?data.asm.at.path:[];  //装配层
            }else {
                ss_lines=[];
                asm_lins=[];
            }
                
            var pin_x_all=[],
                pin_y_all=[],
                ss_line_x_all=[],
                ss_line_y_all=[],
                asm_line_x_all=[],
                asm_line_y_all=[];
            var z=0,
                y=0,
                w=0,
                x=0;
            
            if(pins.length==1){
                pads.forEach(function(p_pin,p_a){
                    let path={},
                        path_name="";
                    path_name=p_pin.t.t.form;
                    if(path_name=="path"){
                        path=p_pin.t.t.path;
                        path.each(function(p_b,line){
                            if(p_b==0){
                                asm_line_x_all[p_b]=line.st_x||0;
                                asm_line_y_all[p_b]=line.st_y||0;
                                w=p_b;
                            }else{
                                asm_line_x_all[w]=line.st_x||0;
                                asm_line_y_all[w]=line.st_y||0;
                            }
                            x=w+1;
                            asm_line_x_all[x]=line.sp_x||0;
                            asm_line_y_all[x]=line.sp_y||0;
                            w=x+1;
                        });
                    }
                    
                });
            }else{
                pins.forEach(function(pin,a){//获取pin的x，y值
                    pin_x_all[a]=pin.x;
                    pin_y_all[a]=pin.y;
                });
            }
            var st_x=0,
                st_y=0,
                sp_x=0,
                sp_y=0;
            ss_lines.forEach(function(ss_line,b){//获取丝印层线的x,y值
                //如果外框是圆形
                if(ss_line.name=="arc"&&(ss_line.st_x==ss_line.sp_x)&&(ss_line.sp_y==ss_line.st_y)){
                    st_x=ss_line.st_x;
                    st_y=(ss_line.st_y-ss_line.r);
                    sp_x=(ss_line.sp_x-2*ss_line.r);
                    sp_y=(ss_line.sp_y+ss_line.r);
                }else{
                    st_x=ss_line.st_x;
                    st_y=ss_line.st_y;
                    sp_x=ss_line.sp_x;
                    sp_y=ss_line.sp_y;
                }
                ss_line_x_all[ss_line_x_all.length]=st_x;
                ss_line_y_all[ss_line_y_all.length]=st_y;
                ss_line_x_all[ss_line_x_all.length]=sp_x;
                ss_line_y_all[ss_line_y_all.length]=sp_y;
            });    
            asm_lins.forEach(function(asm_line,c){//装配层线的x，y值
                //如果外框是圆形
                if(asm_line.name=="arc"){
                    st_x=asm_line.st_x||0;
                    st_y=asm_line.st_y-asm_line.r||0;
                    sp_x=asm_line.sp_x-2*asm_line.r||0;
                    sp_y=asm_line.sp_y+asm_line.r||0;
                }else{
                    st_x=asm_line.st_x||0;
                    st_y=asm_line.st_y||0;
                    sp_x=asm_line.sp_x||0;
                    sp_y=asm_line.sp_y||0;
                }
                
                if(c==0){
                    asm_line_x_all[c]=asm_line.st_x||0;
                    asm_line_y_all[c]=asm_line.st_y||0;
                    w=c;
                }else{
                    asm_line_x_all[w]=asm_line.st_x||0;
                    asm_line_y_all[w]=asm_line.st_y||0;
                }
                
                x=w+1;
                asm_line_x_all[x]=asm_line.sp_x||0;
                asm_line_y_all[x]=asm_line.sp_y||0;
                w=x+1;
            });
            var max_ss_x=Math.max.apply(0, ss_line_x_all.toString().split(',').map(Number)),//丝印层x轴最大坐标
                max_ss_y=Math.max.apply(0, ss_line_y_all.toString().split(',').map(Number)),//丝印层y轴最大坐标
                min_ss_x=Math.min.apply(0, ss_line_x_all.toString().split(',').map(Number)),//丝印层x轴最小坐标
                min_ss_y=Math.min.apply(0, ss_line_y_all.toString().split(',').map(Number));//丝印层y轴最小坐标
            var max_asm_x=Math.max.apply(0, asm_line_x_all.toString().split(',').map(Number)),//装配层x轴最大坐标
                max_asm_y=Math.max.apply(0, asm_line_y_all.toString().split(',').map(Number)),//装配层y轴最大坐标
                min_asm_x=Math.min.apply(0, asm_line_x_all.toString().split(',').map(Number)),//装配层x轴最小坐标
                min_asm_y=Math.min.apply(0, asm_line_y_all.toString().split(',').map(Number));//装配层y轴最小坐标
        
            var max_p_x=Math.max.apply(0, pin_x_all.toString().split(',').map(Number)),//x轴最大坐标
                max_p_y=Math.max.apply(0, pin_y_all.toString().split(',').map(Number)),//y轴最大坐标
                min_p_x=Math.min.apply(0, pin_x_all.toString().split(',').map(Number)),//x轴最小坐标
                min_p_y=Math.min.apply(0, pin_y_all.toString().split(',').map(Number));//y轴最小坐标
            
            //检测pin是否在框线外部
            var sum_x=pin_x_all.concat(ss_line_x_all);//引脚与丝印层
            var sum_y=pin_y_all.concat(ss_line_y_all);
            var sum_max_x=Math.max.apply(0, sum_x.toString().split(',').map(Number)),//x轴最大坐标
                sum_max_y=Math.max.apply(0, sum_y.toString().split(',').map(Number)),//y轴最大坐标
                sum_min_x=Math.min.apply(0, sum_x.toString().split(',').map(Number)),//x轴最小坐标
                sum_min_y=Math.min.apply(0, sum_y.toString().split(',').map(Number));//y轴最小坐标
            
            var p_w=max_p_x/1-min_p_x/1,
                p_h=max_p_y/1-min_p_y/1,
                s_w=max_ss_x/1-min_ss_x/1,
                s_h=max_ss_y/1-min_ss_y/1,
                a_w=max_asm_x/1-min_asm_x/1,
                a_h=max_asm_y/1-min_asm_y/1,
                sum_w=sum_max_x/1-sum_min_x/1,
                sum_h=sum_max_y/1-sum_min_y/1;

            //判断是pin or ss or asm的长宽最大Math.abs：取绝对值
            var img_area_all=[Math.abs(p_w)*Math.abs(p_h),Math.abs(s_w)*Math.abs(s_h),Math.abs(a_w)*Math.abs(a_h),Math.abs(sum_w)*Math.abs(sum_h)];
            var img_area=img_area_all[0],
                img_area_type=0;
            for(var img_a=0;img_a<img_area_all.length;img_a++){
                if(img_area_all[img_a]>img_area){
                    img_area=img_area_all[img_a];
                    img_area_type=img_a;
                }
            }
            let img_xyz_mode = "sum";
            switch(img_area_type){
                case 0: img_xyz_mode = "pin";
                        break;
                case 1: img_xyz_mode = "ss";
                        break;
                case 2: img_xyz_mode = "asm";
                        break; 
            }

            var origin_imgx=0,
                origin_imgy=0;
            
            if(img_xyz_mode=="pin"){
                origin_imgx=(min_p_x+max_p_x)/2;
                origin_imgy=(max_p_y+min_p_y)/2;
            }else if(img_xyz_mode=="ss"){
                origin_imgx=(min_ss_x+max_ss_x)/2;
                origin_imgy=(max_ss_y+min_ss_y)/2;
            }else if(img_xyz_mode=="asm"){
                origin_imgx=(min_asm_x+max_asm_x)/2;
                origin_imgy=(max_asm_y+min_asm_y)/2;
            }else{
                origin_imgx=(sum_min_x+sum_max_x)/2;
                origin_imgy=(sum_max_y+sum_min_y)/2;
            }
            
            // this.data.originimg=[origin_imgx,origin_imgy];  //图形中心
            // this.data.origincanvas=[origin_x,origin_y];     //画布中心
            // this.data.origin=[origin_x-origin_imgx,origin_y+origin_imgy]; //绘图中心

            return {
                x: [sum_min_x, sum_max_x],
                y: [sum_min_y, sum_max_y]
            };
        }
        
    }

    // 与图形有关的计算
    const figureComputed = {
        // 获取图形中心坐标
        getFigureCenter(figure){
            if(figure.type == "pins" || figure.form == "S" || figure.form == "OV" || figure.type == "texts"){
                return {
                    x: figure.data.x,
                    y: figure.data.y
                };
            }
            if(figure.form == "PATH"){
                let range = measureUtil.computedShapeRange(figure);
                return {
                    x: range.x,
                    y: range.y
                };
            }
            if(figure.form == "S" || figure.form == "OV"){
                return {
                    x: figure.data.x,
                    y: figure.data.y
                };
            }
            if(figure.form == "LINE"){
                return {
                    x: (figure.data.sp_x + figure.data.st_x) / 2,
                    y: (figure.data.sp_y + figure.data.st_y) / 2
                }
            }
            if(figure.form == "ARC"){
                if(figure.data.sp_x == figure.data.st_x && figure.data.sp_y == figure.data.st_y){
                    return {
                        x: figure.data.o_x,
                        y: figure.data.o_y
                    }
                }else{
                    return {
                        x: (figure.data.sp_x + figure.data.st_x) / 2,
                        y: (figure.data.sp_y + figure.data.st_y) / 2
                    }
                }
            }

            console.error("无法识别的图形",figure);
            return {
                x:0,
                y:0
            }
        },

        // 判断此图形是否在范围内
        figureInTheRange(figure,range){
            let figureCenter = this.getFigureCenter(figure);
            return figureCenter.x >= range.x[0] && figureCenter.x <= range.x[1] && figureCenter.y >= range.y[0] && figureCenter.y <= range.y[1];
        }
    }

    // 创建图形用到的方法
    const generateFigure = {

        createPad(r,w,h,num,units,type,pinType,outOffset,inOffset,drillOption){
            if(!r && !w && !h){
                return false;
            }
            if(!r){
                r = w>h?h:w;
            }

            if(type === "C"){
                w = r;
                h = r;
            }else{
                w = w || r;
                h = h || r;
            }
            
            let addW = units === "mm"?w+0.1:w+4;
            let addH = units === "mm"?h+0.1:h+4;
            let addR = units === "mm"?r+0.1:r+4;
            
            if(type === "CS"){
                r = r/4;
                addR = addR/4;
            }

            let drillType = "C";

            if(type === "OV"){
                drillType = "OV";
            }

            if(type == "OC"){
                w = r;
                h = r;
                addW = addR;
                addH = addR;
            }

            if(pinType === "via"){
                return {
                    kind: "via",
                    b:{
                        rotate: 0,
                        form: type,
                        w,
                        h,
                        r:r/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    bs_t:{
                        rotate: 0,
                        form: type,
                        w: addW,
                        h: addH,
                        r: addR/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    bs_b:{
                        rotate: 0,
                        form: type,
                        w: addW,
                        h: addH,
                        r: addR/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    t:{
                        rotate: 0,
                        form: type,
                        w,
                        h,
                        r:r/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    ts_t:{
                        rotate: 0,
                        form: type,
                        w: addW,
                        h: addH,
                        r: addR/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    ts_b:{
                        rotate: 0,
                        form: type,
                        w: addW,
                        h: addH,
                        r: addR/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    i:{
                        rotate: 0,
                        form: type,
                        w,
                        h,
                        r:r/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    is_t:{
                        rotate: 0,
                        form: type,
                        w: addW,
                        h: addH,
                        r: addR/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    is_b:{
                        rotate: 0,
                        form: type,
                        w: addW,
                        h: addH,
                        r: addR/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    drill:[
                        {
                            rotate: 0,
                            form: drillType,
                            w: drillOption.w,
                            h: drillOption.h,
                            r: drillOption.r/2,
                            skewing_x: inOffset.x,
                            skewing_y: inOffset.y
                        }
                    ]
                }
            }

            if(pinType === "smt"){
                return {
                    kind: "smt",
                    t:{
                        rotate: 0,
                        form: type,
                        w,
                        h,
                        r:r/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    ts_t:{
                        rotate: 0,
                        form: type,
                        w: addW,
                        h: addH,
                        r: addR/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    ts_b:{
                        rotate: 0,
                        form: type,
                        w: addW,
                        h: addH,
                        r: addR/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    tp_t:{
                        rotate: 0,
                        form: type,
                        w,
                        h,
                        r:r/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    tp_b:{
                        rotate: 0,
                        form: type,
                        w,
                        h,
                        r:r/2,
                        num,
                        skewing_x: outOffset.x,
                        skewing_y: outOffset.y
                    },
                    drill:[]
                }
            }

            if(pinType === "hole"){
                return {
                    kind: "via",
                    drill:[
                        {
                            rotate: 0,
                            form: drillType,
                            w:drillOption.w,
                            h:drillOption.h,
                            r:drillOption.r/2,
                            skewing_x: inOffset.x,
                            skewing_y: inOffset.y
                        }
                    ]
                }
            }
        },

        pad(options){
            let {r,w,h,num,units,type,pinType,outOffset,inOffset,drillOption} = options;
            type = type.toUpperCase();
            return this.createPad(r,w,h,num,units,type,pinType,outOffset,inOffset,drillOption);
        },

        createLine(options){
            let cLine = {
                form:options.form || "LINE",
                type:"path",
                layer:options.layer || "st",
                data:{
                    name:options.form || "LINE",
                    sp_x: options.sp_x || 0,
                    sp_y: options.sp_y || 0,
                    st_x: options.st_x || 0,
                    st_y: options.st_y || 0,
                    o_x: options.o_x ||  0,
                    o_y: options.o_y || 0,
                    arc_r: options.arc_r || "nil",
                    r: options.r || 0,
                    width: options.width
                }
            };
            return cLine;
        },

        // 创建一个类矩形数据
        createAkinRect(options){
            let rect = {
                type:"path",
                form:options.form,
                layer:options.layer || "st",
                data:{
                    name:options.form,
                    x:0,
                    y:0,
                    w:0,
                    h:0,
                    o_x:0,
                    o_y:0,
                    rotate:0,
                    width:options.width
                }
            }
            return rect;
        },

        // 创建一个圆形铜皮
        createCircleShape(options){
            let circle = {
                type:"shapes",
                form:"C",
                layer:options.layer,
                make:"f",
                data:{

                }
            }
        },

        // 创建一个Line数据
        createLineData(options){
            return {
                name:options.form,
                sp_x: 0,
                sp_y: 0,
                st_x: 0,
                st_y: 0,
                o_x:0,
                o_y:0,
                arc_r: options.arc_r || "nil",
                r:0,
                width: options.width || 0
            }
        },

        // 创建一个文字
        createText(options,drawInstance){
            let text = {
                layer: options.layer || "st",
                type: "texts",
                form: "TEXT",
                data: {
                    rotate: options.rotate || 0,
                    name: "TEXT",
                    x: options.x || 0,
                    y: options.y || 0,
                    textheight: 0,
                    textwidth: 0,
                    fontWeight: options.fontWeight || 300,
                    content: options.content || "Text",
                    textblock: options.textblock || 10
                }
            }
            
            if(options.strokeRect){
                text.strokeRect = options.strokeRect;
            }

            if(!drawInstance){
                text.data.textwidth = text.data.content.length * text.data.textblock / 2;
            }else{
                text.data.textwidth = drawInstance.getTxtWidth(text).width;
            }
            text.data.textheight =  text.data.textblock;
            return text;
        },

        // 创建一个三角一脚标识
        createOnePinTMark(options){
            var r = options.r / 2;
            var x = options.x;
            var y = options.y;

            let points = [
                [x, r + y],
                [ Math.sqrt(3) * r / 2 + x , - r / 2 + y ],
                [ - Math.sqrt(3) * r / 2 + x , - r / 2 + y ],
            ]

            if(options.rotate){
                points = util.rotatePoints(points,[x,y],options.rotate);
            }

            let lines = [];

            let lineOptions = {
                form:"LINE",
                st_x: 0,
                st_y: 0,
                sp_x: 0,
                sp_y: 0,
                width: options.r  / 2
            }
            points.forEach((point1,index)=>{
                let point2 = points[ (index + 1) % points.length];
                lineOptions.st_x = point1[0];
                lineOptions.st_y = point1[1];
                lineOptions.sp_x = point2[0];
                lineOptions.sp_y = point2[1];
                lines.push(this.createLine(lineOptions));
            });
            // lines.forEach(line=>{
            //     line.mark = true;
            // })
            return lines;
            // console.log(lines);
        },

        // 创建一个圆形的一脚标识
        createOnePinCMark(options){
            var r = options.r;

            let arcOptions = {
                form:"ARC",
                st_x: 0,
                st_y: 0,
                sp_x: 0,
                sp_y: 0,
                width: r / 2,
                r: r / 4
            }
            let arc = this.createLine(arcOptions);
            // arc.mark = true;
            return arc;
        }
    }

    // 测量所需要的工具
    const measureUtil = {
        // 计算pad的大小
        computedPadSize(padData){
            let {drillRangeList,outPathRange} = this.computedPadRange(padData);

            let drillSize = drillRangeList.map(drillRange=>{
                return {
                    w:Math.abs(drillRange.x[1]-drillRange.x[0]),
                    h:Math.abs(drillRange.y[1]-drillRange.y[0])
                }
            });
            var outPathSize = {
                w:0,
                h:0
            }
            if(outPathRange){
                outPathSize.w = parseFloat(Math.abs(outPathRange.x[1]-outPathRange.x[0]).toFixed(4));
                outPathSize.h = parseFloat(Math.abs(outPathRange.y[1]-outPathRange.y[0]).toFixed(4));
            }else{
                if(drillSize[0]){
                    outPathSize.w = drillSize[0].w;
                    outPathSize.h = drillSize[0].h;
                }
            }
            let padSize = {
                w:outPathSize.w,
                h:outPathSize.h,
                drill:drillSize
            };
            return padSize;
        },

        // 获取pad范围
        computedPadRange(padData){
            let self = this;

            let centerPoint = [0,0];

            let layers = ["b","bs_t","bs_b","bp_t","bp_b","t","ts_t","ts_b","tp_t","tp_b","i","is_t","is_b","ip_t","ip_b"];

            let outPathRange,drillRange,padRange;
            let drillRangeList = [];
            
            layers.forEach(layer=>{
                let layerData = padData[layer];
                if(layerData && !isEmpty(layerData)){
                    // console.log(layerData)
                    let toRange = getLayerRange(layerData);
                    outPathRange = this.compareRange(outPathRange,toRange);
                }
            });
            padRange = outPathRange;

            // console.log(outPathRange);
            padData.drill?.forEach?.(drill=>{
                let toRange = getLayerRange(drill);
                drillRange = this.compareRange(drillRange,toRange);
                drillRangeList.push(toRange);
            });
            padRange = this.compareRange(padRange,drillRange);
            return {
                outPathRange,
                drillRange,
                padRange,
                drillRangeList
            }

            function getLayerRange(layerData){
                let toRange = {
                    x:[0,0],
                    y:[0,0]
                }
                let size = [];
                if(layerData.form === "S" || layerData.form === "CS" || layerData.form === "OV"){
                    size[0] = layerData.w;
                    size[1] = layerData.h;
                    toRange = self.getCloseRange(centerPoint,size);
                }else if(layerData.form === "POLY" || layerData.form === "OC" || layerData.form === "C"){
                    size[0] = size[1] = layerData.r * 2;
                    toRange = self.getCloseRange(centerPoint,size);
                }else if(layerData.form === "PATH"){
                    toRange = self.getPathRange(layerData.path);
                }
                return toRange;
            }
        },

        // 获取pin的范围
        computedPinRange(pinData,padData){
            let {padRange} = this.computedPadRange(padData);
            let pinRange = {
                x:[0,0],
                y:[0,0]
            }
            pinRange.x = [
                padRange.x[0] + pinData.x,
                padRange.x[1] + pinData.x
            ]
            pinRange.y = [
                padRange.y[0] + pinData.y,
                padRange.y[1] + pinData.y
            ]
            return pinRange;
        },

        // 获取普通图形的范围
        computedImageRange(img){
            if(img.type == "path"){
                return this.getPathItemRange(img.data);
            }
            if(img.type == "shapes"){
                return this.getPathRange(img.data)
            }
            if(img.type == "texts"){
                return this.getCloseRange([img.data.x, img.data.y],[img.data.textwidth, img.data.textheight]);
            }
        },

        // 计算shape的大小以及中心点
        computedShapeRange(shapeData){
            let range = this.getPathRange(shapeData.data);
            return {
                w:parseFloat(Math.abs(range.x[1]-range.x[0]).toFixed(4)),
                h:parseFloat(Math.abs(range.y[1]-range.y[0]).toFixed(4)),
                x:parseFloat(((range.x[1]+range.x[0])/2).toFixed(4)),
                y:parseFloat(((range.y[1]+range.y[0])/2).toFixed(4))
            }
        },

        // 获取矩形的范围
        getCloseRange(centerPoint,size){
            var range = {
                x:[centerPoint[0] - (size[0]/2), centerPoint[0] + (size[0]/2)],
                y:[centerPoint[1] - (size[1]/2), centerPoint[1] + (size[1]/2)]
            }
            return range;
        },

        // 获取路径的范围
        getPathRange(path){
            if(!path.length){
                return false;
            }
            var pathRange = null;
            path.forEach((item)=>{
                var pathItemRange = this.getPathItemRange(item);
                pathRange = this.compareRange(pathRange,pathItemRange);
            });
            return pathRange;
        },

        // 获取线段的范围
        getPathItemRange(item){
            var pathItemRange = {};
            var name = item.name.toUpperCase();
            let maxX = 0, minX = 0, maxY = 0, minY = 0;
            
            if(name == "ARC"){
                let isRound = false;
                if(item.st_x > item.sp_x){
                    maxX = item.st_x;
                    minX = item.sp_x;
                    if(item.arc_r == "t"){
                        maxY = -(-item.o_y + item.r);
                        minY = item.st_y;
                        if(-item.st_y > -item.sp_y){
                            minY = item.sp_y;
                            minX = item.o_x - item.r;
                        }
                        else if(-item.st_y < -item.sp_y){
                            minY = item.st_y;
                            maxX = item.o_x + item.r;
                        }
                    }else{
                        maxY = item.st_y;
                        minY = -(-item.o_y - item.r);
                        if(-item.st_y > -item.sp_y){
                            maxY = item.st_y;
                            maxX = item.o_x + item.r;
                        }
                        else if(-item.st_y < -item.sp_y){
                            maxY = item.sp_y;
                            minX = item.o_x - item.r;
                        }
                    }
                }
                else if(item.st_x < item.sp_x){
                    maxX = item.sp_x;
                    minX = item.st_x;
                    if(item.arc_r == "t"){
                        minY = -(-item.o_y - item.r);
                        maxY = item.st_y;
                        if(-item.st_y < -item.sp_y){
                            maxY = item.sp_y;
                            maxX = item.o_x + item.r;
                        }
                        else if(-item.st_y > -item.sp_y){
                            maxY = item.st_y;
                            minX = item.o_x - item.r;
                        }
                    }else{
                        maxY = -(-item.o_y + item.r);
                        minY = item.st_y;
                        if(-item.st_y > -item.sp_y){
                            minY = item.sp_y;
                            maxX = item.o_x + item.r;
                        }
                        else if(-item.st_y < -item.sp_y){
                            minY = item.st_y;
                            minX = item.o_x - item.r;
                        }
                    }
                }
                else{
                    if(item.st_y != item.sp_y){
                        if(item.arc_r == "t"){
                            if(-item.st_y < -item.sp_y){
                                maxY = item.sp_y;
                                minY = item.st_y;
                                maxX = item.o_x + item.r;
                                minX = item.o_x;
                            }
                            else if(-item.st_y > -item.sp_y){
                                maxY = item.st_y;
                                minY = item.sp_y;
                                maxX = item.o_x;
                                minX = item.o_x - item.r;
                            }
                        }else{
                            if(-item.st_y > -item.sp_y){
                                maxY = item.st_y;
                                minY = item.sp_y;
                                maxX = item.o_x + item.r;
                                minX = item.o_x;
                            }
                            else if(-item.st_y < -item.sp_y){
                                maxY = item.sp_y;
                                minY = item.st_y;
                                maxX = item.o_x;
                                minX = item.o_x - item.r;
                            }
                        }
                    }
                    else{
                        isRound = true;
                        maxY = item.o_y + item.r;
                        minY = item.o_y - item.r;
                        maxX = item.o_x + item.r;
                        minX = item.o_x - item.r;
                    }
                }
                if(isRound){
                    pathItemRange = {
                        x:[minX-item.width/2,maxX+item.width/2],
                        y:[minY-item.width/2,maxY+item.width/2]
                    };
                }else{
                    pathItemRange = {
                        x:[minX-item.width/2,maxX+item.width/2],
                        y:[maxY-item.width/2,minY+item.width/2]
                    };
                }
            }
            else if(name == "LINE"){
                if(item.width != 0){
                    var big = {
                        a:Math.abs(item.st_y-item.sp_y),
                        b:Math.abs(item.st_x-item.sp_x)
                    }
    
                    big.c = Math.sqrt(big.a*big.a+big.b*big.b);
    
                    var small = {
                        a:(item.width/2)/big.c * big.a,
                        b:(item.width/2)/big.c * big.b
                    }
                    maxX = item.st_x + small.a > item.sp_x + small.a ? item.st_x + small.a : item.sp_x + small.a;
                    
                    minX = item.st_x - small.a < item.sp_x - small.a ? item.st_x - small.a : item.sp_x - small.a;
                    
                    maxY = item.st_y + small.b > item.sp_y + small.b ? item.st_y + small.b : item.sp_y + small.b;
                    
                    minY = item.st_y - small.b < item.sp_y - small.b ? item.st_y - small.b : item.sp_y - small.b;
                }else{
                    maxX = item.st_x > item.sp_x ? item.st_x : item.sp_x;
                    minX = item.st_x < item.sp_x ? item.st_x : item.sp_x;
                    maxY = item.st_y > item.sp_y ? item.st_y : item.sp_y;
                    minY = item.st_y < item.sp_y ? item.st_y : item.sp_y;
                }
                
                pathItemRange = {
                    x:[minX,maxX],
                    y:[minY,maxY]
                };
            }else if(name == "S" || name == "OV"){
                pathItemRange = this.getCloseRange([item.x, item.y], [item.w, item.h]);
            }else if(name == "OC"){
                pathItemRange = this.getCloseRange([item.x, item.y], [item.r * 2, item.r * 2]);
            }
            return pathItemRange;
        },

        //计算选中图形的边界
        computedLocation:function(parrentData,options){
            var locationRange = null;

            // 分图形判断
            
            // 判断pin的范围
            var pins = [];
            if(options._pin === "click" || options._pin === "lock"){
                options.bright_pin.forEach((pinIndex)=>{
                    // 取pin
                    pins.push(parrentData.pins[pinIndex]);
                });
            }
            else if(options._pin === "all"){
                pins = parrentData.pins.filter(pin=>{
                    return pin.pin_padid == options.bright_pad[0];
                });
            }
            pins.forEach(pin=>{
                var padRange = getPinRange(pin,parrentData.pads);
                locationRange = compareRange(locationRange,padRange);
            });
            
            // 所有的layer
            var layerList = [];
            options.bright_layer.forEach(item=>{
                for(var outKey in parrentData){
                    if(parrentData.hasOwnProperty(outKey) && typeof(parrentData[outKey]) === "object"){
                        for(let key in parrentData[outKey]){
                            if(parrentData[outKey].hasOwnProperty(key) && key == item){
                                layerList[item] = parrentData[outKey][key];
                            }
                        }
                    }
                }
            });

            if(!options.bright_layer.length){
                return {point:CalcRectCore(locationRange),size:CalcRectSize(locationRange)};
            }
            
            options.bright_layer.forEach((item,index)=>{
                var layer = layerList[item];
                
                var path = [];
                if(options._line === "click" || options._line === "lock"){
                    var path = [layer.path[options.bright_line[index]]];
                }
                else if(options._line === "all"){
                    var path = layer.path;
                }
            
                var range = getPathRange(path);
                locationRange = compareRange(locationRange,range);
            
                var texts = [];
                if(options._text === "click" || options._text === "lock"){
                        var texts =  [layer.texts[index]];
                }
                else if(options._text === "all"){
                    var texts = layer.texts;
                }
            
                texts.forEach(text=>{
                    var range = getCloseRange([text.x,text.y],[text.textwidth,text.textheight]);
                    range = getRotateRange(range,text.rotate);
                    locationRange = compareRange(locationRange,range);
                });
            
                var shapes = [];
                if(options._shape === "click" || options._shape === "lock"){
                        var shapes = layer.shapes.filter((shape,index)=>{
                            return options.bright_shape.indexOf(index) != -1;
                        });
                        
                }
                else if(options._shape === "all"){
                    var shapes = layer.shapes;
                }
            
                shapes.forEach((shape,index)=>{
                    var range = {};
                    if(options.bright_f_o[index] == "f" || options._shape === "all"){
                        range = getPathRange(shape.fill);
                        locationRange = compareRange(locationRange,range);
                    }
                    if(options.bright_f_o[index] == "o" || options._shape === "all"){
                        range = getPathRange(shape.outline);
                        locationRange = compareRange(locationRange,range);
                    }
                });
            
            });
            
            // 获取pin的范围
            function getPinRange(pin,pads){
                let padRange = null;
            
                var pad = pads[pads.findIndex((pad)=>{
                    return pad.id == pin.pin_padid;
                })];
            
                for(var prop in pad){
                    if(!pad.hasOwnProperty(prop)){
                        continue;
                    }
                    
                    var padItem = pad[prop];
            
                    if(typeof(padItem) === "object"){
                        var padItemXY = [];
                        var padWH = [];
                        // dirll
                        if(prop == "dirll"){
                            padItem.forEach((dirll)=>{
                                // 圆
                                if(dirll.hole.form == "circle_drill" || dirll.hole.form == "C"){
                                    padWH = [dirll.diameter,dirll.diameter];
                                }
                                // 其它
                                else{
                                    padWH = [dirll.hole.w,dirll.hole.h];
                                }
            
                                padItemXY = [dirll.offset.x + pin.x, dirll.offset.y + pin.y];
            
                                var range = getCloseRange(padItemXY,padWH);
            
                                range = getRotateRange(range,irll.hole.rotate)
            
                                padRange = compareRange(padRange,range);
            
                            });
                        }
                        // 其它
                        else{
                            for(let key in padItem){
                                if(!padItem[key].hasOwnProperty(prop) && !padItem[key].form){
                                    continue;
                                }
                                
                                if(padItem[key].form == "path"){
                                    var range = getPathRange(padItem[key].path);
                                    range = getRotateRange(range,padItem[key].rotate);
                                }else{
            
                                    padItemXY = [padItem[key].skewing_x + pin.x, padItem[key].skewing_y + pin.y];
            
                                    padWH = [padItem[key].w,padItem[key].h];
            
                                    var range = getCloseRange(padItemXY,padWH);
                                    range = getRotateRange(range,padItem[key].rotate);
            
                                }
                                padRange = compareRange(padRange,range);
                            }
                        }
                    }
                }
            
                padRange = getRotateRange(padRange,pin.rotate);
            
                return padRange;
            }
            
            // 获取路径的范围
            function getPathRange(path){
                if(!path.length){
                    return false;
                }
            
                var pathRange = null;
            
                path.forEach(function(item){
                    var name = item.name.toUpperCase();
                    var pathItemRange = {};
                    let maxX = 0, minX = 0, maxY = 0, minY = 0;
                    let isRound = false;
                    if(name == "ARC"){
                        if(item.st_x > item.sp_x){
                            maxX = item.st_x;
                            minX = item.sp_x;
                            if(item.arc_r == "t"){
                                maxY = -(-item.o_y + item.r);
                                minY = item.st_y;
                                if(-item.st_y > -item.sp_y){
                                    minY = item.sp_y;
                                    minX = item.o_x - item.r;
                                }
                                else if(-item.st_y < -item.sp_y){
                                    minY = item.st_y;
                                    maxX = item.o_x + item.r;
                                }
                            }else{
                                maxY = item.st_y;
                                minY = -(-item.o_y - item.r);
                                if(-item.st_y > -item.sp_y){
                                    maxY = item.st_y;
                                    maxX = item.o_x + item.r;
                                }
                                else if(-item.st_y < -item.sp_y){
                                    maxY = item.sp_y;
                                    minX = item.o_x - item.r;
                                }
                            }
                        }
                        else if(item.st_x < item.sp_x){
                            maxX = item.sp_x;
                            minX = item.st_x;
                            if(item.arc_r == "t"){
                                minY = -(-item.o_y - item.r);
                                maxY = item.st_y;
                                if(-item.st_y < -item.sp_y){
                                    maxY = item.sp_y;
                                    maxX = item.o_x + item.r;
                                }
                                else if(-item.st_y > -item.sp_y){
                                    maxY = item.st_y;
                                    minX = item.o_x - item.r;
                                }
                            }else{
                                maxY = -(-item.o_y + item.r);
                                minY = item.st_y;
                                if(-item.st_y > -item.sp_y){
                                    minY = item.sp_y;
                                    maxX = item.o_x + item.r;
                                }
                                else if(-item.st_y < -item.sp_y){
                                    minY = item.st_y;
                                    minX = item.o_x - item.r;
                                }
                            }
                        }
                        else{
                            if(item.st_y != item.sp_y){
                                if(item.arc_r == "t"){
                                    if(-item.st_y < -item.sp_y){
                                        maxY = item.sp_y;
                                        minY = item.st_y;
                                        maxX = item.o_x + item.r;
                                        minX = item.o_x;
                                    }
                                    else if(-item.st_y > -item.sp_y){
                                        maxY = item.st_y;
                                        minY = item.sp_y;
                                        maxX = item.o_x;
                                        minX = item.o_x - item.r;
                                    }
                                }else{
                                    if(-item.st_y > -item.sp_y){
                                        maxY = item.st_y;
                                        minY = item.sp_y;
                                        maxX = item.o_x + item.r;
                                        minX = item.o_x;
                                    }
                                    else if(-item.st_y < -item.sp_y){
                                        maxY = item.sp_y;
                                        minY = item.st_y;
                                        maxX = item.o_x;
                                        minX = item.o_x - item.r;
                                    }
                                }
                            }
                            else{
                                maxY = item.o_y + item.r;
                                minY = item.o_y - item.r;
                                maxX = item.o_x + item.r;
                                minX = item.o_x - item.r;
                            }
                        }
                        if(isRound){
                            pathItemRange = {
                                x:[minX-item.width/2,maxX+item.width/2],
                                y:[minY-item.width/2,maxY+item.width/2]
                            };
                        }else{
                            pathItemRange = {
                                x:[minX-item.width/2,maxX+item.width/2],
                                y:[maxY-item.width/2,minY+item.width/2]
                            };
                        }
                    }
                    else if(name == "LINE"){
                        if(item.width != 0){
                            var big = {
                                a:Math.abs(item.st_y-item.sp_y),
                                b:Math.abs(item.st_x-item.sp_x)
                            }
            
                            big.c = Math.sqrt(big.a*big.a+big.b*big.b);
            
                            var small = {
                                a:(item.width/2)/big.c * big.a,
                                b:(item.width/2)/big.c * big.b
                            }
                            maxX = item.st_x + small.a > item.sp_x + small.a ? item.st_x + small.a : item.sp_x + small.a;
                            
                            minX = item.st_x - small.a < item.sp_x - small.a ? item.st_x - small.a : item.sp_x - small.a;
                            
                            maxY = item.st_y + small.b > item.sp_y + small.b ? item.st_y + small.b : item.sp_y + small.b;
                            
                            minY = item.st_y - small.b < item.sp_y - small.b ? item.st_y - small.b : item.sp_y - small.b;
                        }else{
                            maxX = item.st_x > item.sp_x ? item.st_x : item.sp_x;
                            minX = item.st_x < item.sp_x ? item.st_x : item.sp_x;
                            maxY = item.st_y > item.sp_y ? item.st_y : item.sp_y;
                            minY = item.st_y < item.sp_y ? item.st_y : item.sp_y;
                        }
                        
                        pathItemRange = {
                            x:[minX,maxX],
                            y:[minY,maxY]
                        };
                    }
                    else{
                        console.log(item.name)
                    }
                    pathRange = compareRange(pathRange,pathItemRange);
                });
            
                return pathRange;
            }
            
            // 获取矩形的范围
            function getCloseRange(parrentXY,parrentWH){
                var range = {
                    x:[parrentXY[0] - (parrentWH[0]/2), parrentXY[0] + (parrentWH[0]/2)],
                    y:[parrentXY[1] - (parrentWH[1]/2), parrentXY[1] + (parrentWH[1]/2)]
                }
                return range;
            }
            
            // 获取矩形旋转之后的范围
            function getRotateRange(range,rotate){
                var maxX=0,maxY=0,minX=0,minY=0;
            
                // 获取中心点
                var core = CalcRectCore(range);
            
                var eachNumber = 0;
                range.x.forEach((x)=>{
                    range.y.forEach((y)=>{
                        eachNumber++;
                        var x1=(x-core[0])*Math.cos(rotate * Math.PI / 180)-(y-core[1])*Math.sin(rotate * Math.PI / 180)+core[0];
                        var y1=(y-core[1])*Math.cos(rotate * Math.PI / 180)+(x-core[0])*Math.sin(rotate * Math.PI / 180)+core[1];
                        if(eachNumber == 1){
                            maxX = x1;
                            maxY = y1;
                            minX = x1;
                            minY = y1;
                        }else{
                            maxX = maxX < x1 ? x1 : maxX;
                            maxY = maxY < y1 ? y1 : maxY;
                            minX = minX < x1 ? minX : x1;
                            minY = minY < y1 ? minY : y1;
                        }
                    });
                });
            
                return {x:[minX,maxX],y:[minY,maxY]};
            }
            
            // 比较范围
            function compareRange(range,toRange){
                if(toRange === false){
                    return range;
                }
                if(!range){
                    return toRange;
                }
                range.x[0] = toRange.x[0] < range.x[0] ? toRange.x[0] : range.x[0];
                range.x[1] = toRange.x[1] > range.x[1] ? toRange.x[1] : range.x[1];
                range.y[0] = toRange.y[0] < range.y[0] ? toRange.y[0] : range.y[0];
                range.y[1] = toRange.y[1] > range.y[1] ? toRange.y[1] : range.y[1];
                return range;
            }
            
            // 计算矩形的中心坐标
            function CalcRectCore(range){
                if(range.x[1]==null){
                    return point; 
                }
                var point = [
                    (range.x[1] + range.x[0])/2,
                    (range.y[1] + range.y[0])/2
                ]
                return point;
            }
            
            // 计算矩形的宽高
            function CalcRectSize(range){
                var size = [
                    Math.abs(range.x[1] - range.x[0]),
                    Math.abs(range.y[1] - range.y[0])
                ]
                return size;
            }

            let point = CalcRectCore(locationRange);
            let size = CalcRectSize(locationRange);
            return {point,size};
        },

        // 比较两个范围
        compareRange(range,toRange){
            if(!toRange){
                return {
                    x:[
                        range.x[0],
                        range.x[1]
                    ],
                    y:[
                        range.y[0],
                        range.y[1]
                    ]
                };
            }
            if(!range){
                return {
                    x:[
                        toRange.x[0],
                        toRange.x[1]
                    ],
                    y:[
                        toRange.y[0],
                        toRange.y[1]
                    ]
                };
            }
            var compare = {
                x:[0,0],
                y:[0,0]
            }
            compare.x[0] = toRange.x[0] < range.x[0] ? toRange.x[0] : range.x[0];
            compare.x[1] = toRange.x[1] > range.x[1] ? toRange.x[1] : range.x[1];
            compare.y[0] = toRange.y[0] < range.y[0] ? toRange.y[0] : range.y[0];
            compare.y[1] = toRange.y[1] > range.y[1] ? toRange.y[1] : range.y[1];
            return compare;
        }
    }
 
    /**
     * @constructor
     * @param {object} options
     * @param {object} options.encaData
     * @param {HTMLElement|string} options.parent
     * @param {?boolean} options.grid
     * @param {?boolean} options.edit
     */
    function DrawEncapsulation(options){
        this.count = ++count;
        if(!options){
            throw "TYPE ERROR:请传入初始化参数!"
                  +"\n{"
                  +"\n  encaData: object"
                  +"\n  parent: HTMLElement | string"
                  +"\n  grid: boolean | null"
                  +"\n  edit: boolean | null"
                  +"\n}";
        }
        this.config = {
            edit:!!options.edit,
            grid:!!options.grid
        }
        this.imgConfig = {
            // 每次缩放的倍速
            zoom:1.2,
            // 格点大小
            gridSize:{
                x:0.5,
                y:0.5
            },
            // 单位制
            units:"mm",

            // 是否是镜像
            mirror:false,

            // 旋转角度
            rotate: 0
        }
        this.editConfig = {
            smallDist:{
                x:0,
                y:0
            },
            editLayer:"st"
        }
        // 图形状态
        this.status = {
            // 编辑
            edit:false,
            // 移动
            move:false,
            // 缩放
            scroll:false,
            // 插入
            insert:false,
            // 触摸
            touch:"run",
            // 测量
            measure:false,
            
            // 是否框选
            boxChoose:false,

            resetOrigin:false,

            mirrorCopy:false,

            flag:false,

            // 是否显示pin的引脚信息
            pinCoord: false
        }
        /**
         * @type HTMLElement | false
         * 绘图节点的父节点
         */
        this.parent = util.getElement(options.parent);
        if(!this.parent){
            throw "类型错误：parent不是一个HTML节点或者不是一个正确的c3选择器"
        }
        /**
         * canvas列表
         */
        this.canvas = options.share?canvasManager.generateShareCanvas(this.parent,options.edit,options.grid):canvasManager.generateCanvas(this.parent,options.edit,options.grid);
        /**
         * canvas的父节点
         */
        this.canvasParent = this.canvas.canvas_global.parentNode;
        /**
         * @type number[]
         */
        this.canvasSize = [this.parent.clientWidth,this.parent.clientHeight];
        /**
         * @type drawDefParams['imgRecord']
         * 记录图形信息
         */
        this.imgRecord = JSON.parse(JSON.stringify(drawDefParams.imgRecord));
        /**
         * @type {}
         */
        this.encaData = handleUtil.formatEncaData(options.encaData);
        /**
         * @type drawDefParams['imgStyleConfig']
         */
        this.imgStyleConfig = JSON.parse(JSON.stringify(drawDefParams.imgStyleConfig));
        /**
         * @type drawDefParams['bright_img']
         * 选中的图形信息
         */
        this.bright_img = JSON.parse(JSON.stringify(drawDefParams.bright_img));
        /**
         * 当前缩放倍数
         */
        this.scale = 0.2;
        /**
         * 当前显示的层级
         */
        this.layer = {
            boardLayer:[],
            pinLayer:[]
        }
        /**
         * 是否允许进行绘制
         */
        this.allowDraw = false;
        /**
         * 当前原点所在位置
         */
        this.origin = {
            x:0,
            y:0
        }
        /**
         * @type {{
         * imgDataTable:[],
         * drawOriginData:[],
         * drawImgDAta:{
         *  paths:[],
         *  shapes:[],
         *  pins:[],
         *  texts:[]
         * }
         * }}
         */
        this.figureData = {
            // 转换之后的原始图形数据
            imgDataTable:[],
            // 当前绘制图形的原始数据
            drawOriginData:[],
            // 显示在演示层的图形数据
            previewData:[],
            // 编辑层预览的图形数据
            editPreviewData:[],
            // 当前编辑的图形数据
            editData:[],
            // 当前测量选择
            measureData:{
                start:{},
                end:{},
                dist:0
            },
            // 重置原点选择的图形
            resetOriginData:{
                // 是否选中了第一个
                selectStart:false,
                startImage:[]
            },
            // 当前选择的图形
            selectData:[]
        },

        // 用于存放临时的图形
        this.temporaryData = {
            mirrorCopyData:[],
            // pin的引脚信息
            pinCoordInfo:{}
        }

        // 历史记录
        this.history = {
            historyList:[],
            nowStatus:0
        }

        // 当期已经绘制的图形（y轴取反，乘了缩放倍速）
        this.drawImage = {
            // 绘制的基础图形
            base:{},
            preview:{},
            top:{}
        }

        this.toolbar_pin_windlist = []; // 编辑pad记录

        if(!this.encaData || !this.encaData.img_data){
            throw "Type Error: encaData is error data";
        }

        // 处理钩子函数
        this.hook = options.hook;

        // 转换数据
        this.figureData.imgDataTable = handleUtil.handlerImg(this.encaData.img_data);

        this.imgRecord.pads = handleUtil.handlerPad(this.encaData.img_data.pads);

        this.imgRecord.pads_id = this.imgRecord.pads.length;

        this.imgRecord.pins_id = this.encaData.img_data.pins?this.encaData.img_data.pins.length : 0;

        // id总计
        this.imgRecord.countId = this.figureData.imgDataTable.length;

        this.drawObj = {};

        if(options.grid){
            this.drawObj.drawGrid = new ImgDraw(this.canvas.canvas_grid);
        }

        if(options.edit){
            this.drawObj.drawPreview = new ImgDraw(this.canvas.canvas_preview);
            this.drawObj.drawTop = new ImgDraw(this.canvas.canvas_top);
        }

        this.drawObj.drawEnca = new ImgDraw(this.canvas.canvas_global);
        this.drawObj.drawShape = new ImgDraw(this.canvas.canvas_shape);
        this.drawObj.drawFlag = new ImgDraw(this.canvas.canvas_flag);

        this.init();

        this.inited = true;
    }

    // 绘制所用到的方法
    const drawEncaMethods = {
        init(){
            this.imgConfig.units = this.encaData.units;
            if(this.imgConfig.units === "mm"){
                this.imgConfig.gridSize.x = 0.5;
                this.imgConfig.gridSize.y = 0.5;
                this.editConfig.smallDist.x = 0.5;
                this.editConfig.smallDist.y = 0.5;
            }else{
                this.imgConfig.gridSize.x = 39.37;
                this.imgConfig.gridSize.y = 39.37;
                this.editConfig.smallDist.x = 39.37;
                this.editConfig.smallDist.y = 39.37;
            }

            // 获取图形的中心坐标
            let range = handleUtil.getEncaRange(this.encaData.img_data);

            let encaCenter = [(range.x[0] + range.x[1]) / 2, (range.y[0] + range.y[1]) / 2];

            this.imgRecord.encaCenter = encaCenter;

            this.imgRecord.encaRange = range;

            console.log(range,encaCenter);

            // 计算默认缩放倍数
            let w = Math.abs(range.x[1] - range.x[0]), h =  Math.abs(range.y[1] - range.y[0]);
            
            // console.log( this.canvasSize[0],w)
            // this.scale = this.canvasSize[0] * 0.5 / w / 39.37;

            let scale = this.imgConfig.units == "mm" ? this.scale * 39.37:this.scale;
            // let scale = w;

            let origin = {
                x:this.canvasSize[0]/2 - encaCenter[0] * scale,
                y:this.canvasSize[1]/2 + encaCenter[1] * scale
            }

            Event.trigger("padUpdated",util.copyObject(this.imgRecord.pads));

            // 节流版绘制
            this.draw = util.throttle(this.onceDraw,16);

            // 整体重绘
            this.wholeRedraw = util.throttle(()=>{
                this.oneWholeRedraw();
            },16);
            this.initEvent();

            this.setOrigin(origin,false);
        },

        initEvent(){
            let resize = ()=>{
                this.resize();
            };

            window.addEventListener("resize",resize);

            var mousewheelTrigger = util.throttle((e)=>{
                Event.trigger("mousewheel",e);
            },16);

            var mousemoveTrigger = util.throttle((e)=>{
                Event.trigger("mousemove",e);
            },8);
            
            // 放大缩小事件
            this.canvasParent.addEventListener("wheel",mousewheelTrigger,{ passive: true });

            // 鼠标移动
            this.canvasParent.addEventListener("mousemove",mousemoveTrigger);


            // 鼠标按下
            this.canvasParent.addEventListener("mousedown",mousedownTrigger);

            // 鼠标抬起
            this.canvasParent.addEventListener("mouseup",mouseupTrigger);

            // 鼠标右键
            this.canvasParent.addEventListener("contextmenu",contextmenuTirgger);

            // 鼠标双击
            this.canvasParent.addEventListener("dblclick",dblclickTirgger);

            // 鼠标单击
            this.canvasParent.addEventListener("click",clickTirgger);

            function mousedownTrigger(e){
                Event.trigger("mousedown",e);
            }

            function mouseupTrigger(e){
                Event.trigger("mouseup",e);
            }

            function contextmenuTirgger(e){
                Event.trigger("contextmenu",e);
            }

            function dblclickTirgger(e){
                Event.trigger("dblclick",e);
            }

            function clickTirgger(e){
                Event.trigger("click",e);
            }

            this.clearEvent = function(){
                // 放大缩小事件
                this.canvasParent.removeEventListener("wheel",mousewheelTrigger,{ passive: true });

                // 鼠标移动
                this.canvasParent.removeEventListener("mousemove",mousemoveTrigger);


                // 鼠标按下
                this.canvasParent.removeEventListener("mousedown",mousedownTrigger);

                // 鼠标抬起
                this.canvasParent.removeEventListener("mouseup",mouseupTrigger);

                // 鼠标右键
                this.canvasParent.removeEventListener("contextmenu",contextmenuTirgger);

                // 鼠标双击
                this.canvasParent.removeEventListener("dblclick",dblclickTirgger);

                // 鼠标单击
                this.canvasParent.removeEventListener("click",clickTirgger);

                this.offBaseEvent();

            }

            this.openBoxChoose();
            
            this.onBaseEvent();
            
            this.openMoveSelectImage();
        },

        // 清除事件
        clearEvent(){},

        // 订阅基础事件
        onBaseEvent(){
            // 缩放
            let zoomEvent = (e)=>{
                if(this.status.move){
                    return;
                }
                this.status.scroll = true;
                let scale = this.scale;
                let zoom = this.imgConfig.zoom;
                let mouseSite = this.getMousePoint(e);
                let origin = {
                    x:this.origin.x,
                    y:this.origin.y
                }
                if(this.imgConfig.mirror){
                    // origin.x = this.canvasSize[0] -  origin.x;
                    mouseSite.x = this.canvasSize[0] - mouseSite.x;
                }
                let detail = e.deltaY;
                // 缩小
                if(detail > 0){
                    scale/=zoom;
                    this.origin.x = mouseSite.x + (origin.x - mouseSite.x) / zoom;
                    this.origin.y = mouseSite.y + (origin.y - mouseSite.y) / zoom;
                }
                // 放大
                else{
                    scale*=zoom;
                    this.origin.x = mouseSite.x + (origin.x - mouseSite.x) * zoom;
                    this.origin.y = mouseSite.y + (origin.y - mouseSite.y) * zoom;
                }
                this.setScale(scale,false);
                this.setOrigin(this.origin,false);
                this.oneWholeRedraw();
            };

            // 拖拽画布
            let dragCanvas = (e)=>{
                if(e.button === 1){
                    this.status.move = true;
                    let start = [e.pageX,e.pageY];
                    let startOrigin = [this.origin.x,this.origin.y];
                    let changeOrigin = util.throttle((e)=>{
                        let end = [e.pageX,e.pageY];
                        let offset = {
                            x: (end[0] - start[0]) * (this.imgConfig.mirror ? -1 : 1),
                            y: end[1] - start[1]
                        }
                        this.setOrigin({
                            x:startOrigin[0] + offset.x,
                            y:startOrigin[1] + offset.y,
                        });
                        // this.setOrigin({
                        //     x:startOrigin[0] + (end[0]-start[0]),
                        //     y:startOrigin[1] + (end[1]-start[1]),
                        // });
                    },6);
                    let removeListen = ()=>{
                        this.status.move = false;
                        window.removeEventListener("mousemove",changeOrigin);
                        window.removeEventListener("mouseup",removeListen);
                    }
                    window.addEventListener("mousemove",changeOrigin);
                    window.addEventListener("mouseup",removeListen);
                }
            };

            // 移动选择
            let moveSelect = (e)=>{
                if(this.status.touch==="run"){
                    !this.status.move && this.pointsToImage(this.getMousePoint(e));
                }
                let originPoint = this.toCanvasOffsetPoint(this.toPoint(this.getMousePoint(e)));
                Event.trigger("mousePointMove",originPoint)

            }

            // 禁止右键默认事件
            let preventDefaultRightClick = (e)=>{
                e.preventDefault();
            };

            Event.on("mousewheel",zoomEvent);

            Event.on("mousedown",dragCanvas);
            
            Event.on("mousemove",moveSelect);

            Event.on("contextmenu",preventDefaultRightClick);

            this.offBaseEvent = function(){
                Event.off("mousewheel",zoomEvent);

                Event.off("mousedown",dragCanvas);
                
                Event.off("mousemove",moveSelect);
    
                Event.off("contextmenu",preventDefaultRightClick);
            }
        },

        // 取消默认基础事件
        offBaseEvent(){},

        /**
         * @param {[]} imgList 
         * @param {[]} layer 
         */
        getPins(layer){
            let layerList = layer.filter(util.pinLayerMap);
    
            if(!layerList.length) return [];

            layerList = [...new Set(layerList)];

            let imgList = this.figureData.imgDataTable.filter(imgItem=>{
                if(imgItem.type==="pins"){
                    return layerList.findIndex(lay=>lay===imgItem.pin_layer) !== -1;
                }
            });

            return JSON.parse(JSON.stringify(imgList));
        },

        /**
         * @param {string[]} layer 
         * @returns []
         */
        getLayer(layer){
            let layerList = layer.filter(util.layerMap);
            if(!layerList.length) return [];
            layerList = [...new Set(layerList)];

            let imgList = this.figureData.imgDataTable.filter(imgItem=>{
                if(imgItem.type === "pins") return;
                return layerList.findIndex(lay=>lay===imgItem.layer) !== -1;
            });

            return JSON.parse(JSON.stringify(imgList));
        },

        drawGrid(){
            let scale = this.imgConfig.units === "mm"?this.scale*39.37:this.scale;

            let drawSize = {
                x:this.imgConfig.gridSize.x * scale,
                y:this.imgConfig.gridSize.y * scale
            }
            this.drawObj.drawGrid.setGrid(drawSize);
        },

        // 设置板层和引脚层进行绘制
        setLayersDraw(boardLayer,pinLayer){
            this.layer.boardLayer = util.copyObject(boardLayer);
            this.layer.pinLayer = util.copyObject(pinLayer);
            this.layerDraw();
        },

        setBoardLayersDraw(boardLayer){
            this.layer.boardLayer = boardLayer;
            this.layerDraw();
        },

        setPinLayersDraw(pinLayer){
            this.layer.pinLayer = pinLayer;
            this.layerDraw();
        },

        layerDraw(){
            let imgList = this.getLayer(this.layer.boardLayer);
            let pinImgList = this.getPins(this.layer.pinLayer);
            this.figureData.drawOriginData = imgList.concat(pinImgList);
            this.drawImage.base = this.transformDrawImage(this.figureData.drawOriginData);
            this.draw();
        },

        // 将原始数据表转成绘图数据
        transformDrawImage(imgList){
            let scale = this.scale;
            let units = this.imgConfig.units;
            if(units=="mm"){
                scale*= 39.37;
            }
            let imageObj = handleUtil.imageSplit(imgList);
            imageObj.paths.forEach(path=>{
                path.form = path.form.toUpperCase();
                path.data.width*=scale;
                if(path.isPreview){
                    path.strokeStyle = "orange";
                }else{
                    path.strokeStyle = this.imgStyleConfig.layer[path.layer].path.color_line;
                }
                if(path.form === "LINE" || path.form === "ARC"){
                    path.data.o_x*=scale;
                    path.data.o_y*=-scale;
                    path.data.r*=scale;
                    path.data.sp_x*=scale;
                    path.data.sp_y*=-scale;
                    path.data.st_x*=scale;
                    path.data.st_y*=-scale;
                    path.data.arc_r = path.data.arc_r === "nil";
                    return;
                }
                if(path.form === "S" || path.form === "OV"){
                    path.data.x*=scale;
                    path.data.y*=-scale;
                    path.data.w*=scale;
                    path.data.h*=scale;
                    return;
                }
            });
            imageObj.shapes.forEach(shape=>{
                let form = shape.form.toUpperCase();
                if(shape.isPreview){
                    shape.fillStyle = "orange";
                }else{
                    shape.fillStyle = this.imgStyleConfig.layer[shape.layer].shape.color_fill;
                }
                if(form === "PATH"){
                    shape.data.forEach(line=>{
                        line.o_x*=scale;
                        line.o_y*=-scale;
                        line.r*=scale;
                        line.sp_x*=scale;
                        line.sp_y*=-scale;
                        line.st_x*=scale;
                        line.st_y*=-scale;
                        line.width*=scale;
                        line.arc_r = line.arc_r === "nil";
                    });
                }
            });
            imageObj.texts.forEach(text=>{
                text.data.textheight *= scale;
                text.data.textwidth *= scale;
                text.data.x *= scale;
                text.data.y *= -scale;
                if(text.isPreview){
                    text.fillStyle = "orange"
                }else{
                    text.fillStyle = this.imgStyleConfig.layer[text.layer].text.color_text;
                }
                // let length = text.data.content.length;
                
                text.data.textblock = text.data.textheight
            });
            imageObj.pins.forEach(pin=>{
                if(pin.isPreview){
                    if(pin.pin_layer === "drill"){
                        pin.fillStyle = "#FFCC00";
                    }else{
                        pin.fillStyle = "orange";
                    }
                    // pin.alpha = 0.1;
                }else{
                    pin.fillStyle = this.imgStyleConfig.pin.color[pin.pin_layer];
                }
                pin.data.x*= scale;
                pin.data.y*= -scale;
                pin.data.skewing_x*=scale;
                pin.data.skewing_y*=-scale;
                if(pin.data.form === "PATH"){
                    pin.data.path.forEach(path=>{
                        path.width*= scale;
                        path.o_x*=scale;
                        path.o_y*=-scale;
                        path.r*=scale;
                        path.sp_x*=scale;
                        path.sp_y*=-scale;
                        path.st_x*=scale;
                        path.st_y*=-scale;
                        path.arc_r = path.arc_r === "nil"
                    });
                }else{
                    pin.data.w*= scale;
                    pin.data.h*= scale;
                    pin.data.r*= scale;
                    pin.data.width*= scale;
                }
                
            });
            return imageObj;
        },

        setScale(scale,allowDraw){
            if(typeof allowDraw === "undefined"){
                allowDraw = true;
            }
            this.scale = scale;
            this.drawImage.base = this.transformDrawImage(this.figureData.drawOriginData);
            // if(this.status.edit || this.status.insert){
            //     this.figureData.previewData = this.transformDrawImage(this.figureData.editData);
            // }
            Event.trigger("canvasViewTransform",{scale,type:"scale"});
            if(!!allowDraw){
                this.wholeRedraw();
            }
        },

        setOrigin(origin,allowDraw){
            if(!origin){
                console.error("原点有误！");
                return;
            }
            if(typeof allowDraw === "undefined"){
                allowDraw = true;
            }
            this.origin.x = origin.x;
            this.origin.y = origin.y;
            if(this.drawObj.drawGrid){
                this.drawObj.drawGrid.setOrigin(origin);
            }
            this.drawObj.drawEnca.setOrigin(origin);
            this.drawObj.drawShape.setOrigin(origin);
            this.drawObj.drawPreview.setOrigin(origin);
            this.drawObj.drawTop.setOrigin(origin);
            this.drawObj.drawFlag.setOrigin(origin);
            Event.trigger("canvasViewTransform",{origin,type:"origin"});
            if(!!allowDraw){
                this.wholeRedraw();
            }
        },

        // 设置canvas的旋转
        setCanvasRotate(rotate,allowDraw){
            this.drawObj.drawEnca.setCanvasRotate(rotate);
            this.drawObj.drawShape.setCanvasRotate(rotate);
            this.drawObj.drawPreview.setCanvasRotate(rotate);
            this.drawObj.drawTop.setCanvasRotate(rotate);
            this.drawObj.drawFlag.setCanvasRotate(rotate);
            if(!!allowDraw){
                this.wholeRedraw();
            }
        },

        // 当窗口大小改变时重新计算原点位置
        resize(){
            let w = this.parent.clientWidth;
            let h = this.parent.clientHeight;
            let scaleNum = [w/this.canvasSize[0],h/this.canvasSize[1]];
            let origin = {
                x:this.origin.x * scaleNum[0],
                y:this.origin.y * scaleNum[1]
            }

            this.canvasSize = [w,h];
            
            canvasManager.resize(this.canvas,[w,h])
            
            this.setOrigin(origin);
        },

        onceDraw(){
            this.drawGrid();
            let {pins,texts,paths,shapes} = util.copyObject(this.drawImage.base);
            this.drawObj.drawEnca.clear();
            this.drawObj.drawShape.clear();
            
            this.drawObj.drawEnca.redrawAll({pins,texts,paths});
            this.drawObj.drawShape.redrawAll({shapes});
        },

        oneWholeRedraw(){
            this.onceDraw();
            this.drawPreview();
            this.drawMeasure();
            
            // this.sendBoxChooseRange();
            if(this.status.flag){
                this.showFlagOrderBit();
            }
        },

        // 清除所有层的绘制
        clearAllDraw(){
            this.drawObj.drawGrid && this.drawObj.drawGrid.clear();
            this.drawObj.drawPreview && this.drawObj.drawPreview.clear();
            this.drawObj.drawEnca && this.drawObj.drawEnca.clear();
            this.drawObj.drawShape && this.drawObj.drawShape.clear();
            this.drawObj.drawTop && this.drawObj.drawTop.clear();
            this.drawObj.drawFlag && this.drawObj.drawFlag.clear();
        }
    }

    // 控制显示相关的方法
    const displayControl = {
        // 镜像显示
        showMirror(){
            this.imgConfig.mirror = true;
            this.canvasParent.style.transform = "rotateY(180deg)";
        },

        // 关闭镜像显示
        closeMirror(){
            this.imgConfig.mirror = false;
            this.canvasParent.style.transform = "";
        }
    }

    // 历史记录方法
    const historyMethods = {
        _update(eventName){
            let historyItem = {
                type:"update",
                event:eventName,
                oldData:{},
                newData:{}
            };
            return {
                start(oldData){
                    historyItem.oldData = util.copyObject(oldData);
                },
                finish:(newData)=>{
                    historyItem.newData = util.copyObject(newData);
                    if(this.history.nowStatus < this.history.historyList.length){
                        this.history.historyList.splice(this.history.nowStatus);
                    }
                    this.history.historyList.push(historyItem);
                    this.history.nowStatus++;
                }
            }
        },

        _insert(insertInfo){
            insertInfo = util.copyObject(insertInfo);
            let historyItem = {
                type:"insert",
                event:insertInfo.type,
                insertInfo
            };
            if(this.history.nowStatus < this.history.historyList.length){
                this.history.historyList.splice(this.history.nowStatus);
            }
            this.history.historyList.push(historyItem);
            this.history.nowStatus++;
        },

        _delete(eventName,deleteInfo){
            let historyItem = {
                type:"delete",
                event:eventName,
                deleteInfo:util.copyObject(deleteInfo)
            };
            if(this.history.nowStatus < this.history.historyList.length){
                this.history.historyList.splice(this.history.nowStatus);
            }
            this.history.historyList.push(historyItem);
            this.history.nowStatus++;
        },

        _deleteImgTableImage(fn){
            for(let i = 0, l = this.figureData.imgDataTable.length; i < l; i++){
                let img = this.figureData.imgDataTable[i];

                let isDelete = fn.call(this,img);

                if(isDelete){
                    this.figureData.imgDataTable.splice(i--,1);
                    l--;
                };
            }
        },

        backout(){
            if(!this.history.nowStatus){
                return;
            }

            var self = this;

            var historyItem = util.copyObject(this.history.historyList[--this.history.nowStatus]);

            if(historyItem.type == "update"){
                _backoutUpdate(historyItem,self);
            }else if(historyItem.type == "insert"){
                _backoutInsert(historyItem,self);
            }else if(historyItem.type == "delete"){
                _backoutDelete(historyItem,self);
            }

            self.figureData.selectData = [];

            self.setPreview([]);

            self.drawPreview();

            self.layerDraw();

            function _backoutUpdate(historyItem,self){
                if(historyItem.event == "align" || historyItem.event == "rotate"){
                    self._deleteImgTableImage(function(img){
                        let newImgIndex = historyItem.newData.findIndex(newImg=>newImg.id == img.id);
                        if(~newImgIndex){
                            historyItem.newData.splice(newImgIndex,1);
                            return true;
                        }
                        return false;
                    });
                    self.figureData.imgDataTable.push(...historyItem.oldData);
                    return;
                }
                if(historyItem.event == "resetOrigin"){
                    self._resetOrigin({
                        x: -historyItem.newData.x,
                        y: -historyItem.newData.y
                    });
                    return;
                }
                if(historyItem.event == "edit"){
                    self._deleteImgTableImage(function(img){
                        let newImgIndex = historyItem.newData.imgList.findIndex(newImg=>newImg.id == img.id);
                        if(~newImgIndex){
                            historyItem.newData.imgList.splice(newImgIndex,1);
                            return true;
                        }
                        return false;
                    });
                    self.figureData.imgDataTable.push(...historyItem.oldData.imgList);
                    if(historyItem.newData.editedPad){
                        self.addPads([historyItem.oldData.pad]);
                    }
                    return;
                }
            }

            function _backoutInsert(historyItem,self){
                var insertInfo = historyItem.insertInfo;
                let inserImgIds = [];
                if(historyItem.event == "pin"){
                    inserImgIds = insertInfo.insertData.pins.map(pin=>pin.id);
                    let inserImgIdMap = makeMap(inserImgIds.join());
                    self._deleteImgTableImage(function(img){
                        return inserImgIdMap(img.id);
                    });
                    if(self._clearInvalidPad().length){
                        Event.trigger("padUpdated",util.copyObject(self.imgRecord.pads));
                    }
                }else{
                    inserImgIds = insertInfo.insertData.map(img=>img.id);
                    let inserImgIdMap = makeMap(inserImgIds.join());
                    self._deleteImgTableImage(function(img){
                        return inserImgIdMap(img.id);
                    });
                }
            }

            function _backoutDelete(historyItem,self){
                var deleteInfo = historyItem.deleteInfo;
                self.figureData.imgDataTable.push(...deleteInfo.deleteImages);

                if(historyItem.event == "pin" || historyItem.event == "select"){
                    if(deleteInfo.deletePads.length){
                        self.addPads(deleteInfo.deletePads);
                    }
                }
            }
        },

        recover(){
            if(this.history.nowStatus == this.history.historyList.length){
                return;
            }
            let self = this;
            var historyItem = util.copyObject(this.history.historyList[this.history.nowStatus++]);

            // console.log(this.history.nowStatus);

            if(historyItem.type == "update"){
                _recoverUpdate(historyItem,self);
            }else if(historyItem.type == "delete"){
                _recoverDelete(historyItem,self);
            }else if(historyItem.type == "insert"){
                _recoverInsert(historyItem,self);
            }

            self.figureData.selectData = [];

            self.setPreview([]);

            self.drawPreview();

            self.layerDraw();

            function _recoverUpdate(historyItem,self){
                if(historyItem.event == "align" || historyItem.event == "rotate"){
                    self._deleteImgTableImage(function(img){
                        let newImgIndex = historyItem.oldData.findIndex(newImg=>newImg.id == img.id);
                        if(~newImgIndex){
                            historyItem.oldData.splice(newImgIndex,1);
                            return true;
                        }
                        return false;
                    });
                    self.figureData.imgDataTable.push(...historyItem.newData);
                    return;
                }
                if(historyItem.event == "resetOrigin"){
                    self._resetOrigin(historyItem.newData);
                    return;
                }
                if(historyItem.event == "edit"){
                    self._deleteImgTableImage(function(img){
                        let newImgIndex = historyItem.oldData.imgList.findIndex(newImg=>newImg.id == img.id);
                        if(~newImgIndex){
                            historyItem.oldData.imgList.splice(newImgIndex,1);
                            return true;
                        }
                        return false;
                    });
                    self.figureData.imgDataTable.push(...historyItem.newData.imgList);
                    if(historyItem.newData.editedPad){
                        self.addPads([historyItem.newData.pad]);
                    }
                    return;
                }
            }

            function _recoverDelete(historyItem,self){
                var deleteInfo = historyItem.deleteInfo;

                let recoverImgIds = deleteInfo.deleteImages.map(img=>img.id);

                let recoverImgIdMap = makeMap(recoverImgIds.join());

                self._deleteImgTableImage(function(img){
                    return recoverImgIdMap(img.id);
                });

                if(historyItem.event == "pin" || historyItem.event == "select"){
                    if(self._clearInvalidPad().length){
                        Event.trigger("padUpdated",util.copyObject(self.imgRecord.pads));
                    }
                }
            }

            function _recoverInsert(historyItem,self){
                var insertInfo = historyItem.insertInfo;
                let inserImg = [];
                if(historyItem.event == "pin"){
                    inserImg = insertInfo.insertData.pins;
                    self.figureData.imgDataTable.push(...inserImg);
                    if(insertInfo.form !== "SELF"){
                        self.addPads(insertInfo.insertData.pads);
                    }
                }else{
                    inserImg = insertInfo.insertData;
                    self.figureData.imgDataTable.push(...inserImg);
                }
                
            }
        }
    }

    // 框选图形
    const boxChooseMethods = {

        // 开启框选
        openBoxChoose(){
            let self = this;

            let boxChoose = false;

            let boxPoint = {
                start:{
                    x: 0,
                    y: 0
                },
                end:{
                    x: 0,
                    y: 0
                }
            }

            var selectData = [];

            // 开始框选
            let startBoxChoose = (e)=>{
                var mousePoint = this.getMousePoint(e);
                if(this.getImageToPoint(this.toPoint(mousePoint),null,{oneFigure:true}).length){
                    return;
                }
                if(e.button == 0 && !this.status.measure && !this.status.resetOrigin && !this.status.insert && !this.status.edit && !this.status.mirrorCopy){
                    boxChoose = true;
                    boxPoint.start = mousePoint;

                
                    self.figureData.selectData = [];
    
                    self.drawPreview();

                    this.sendBoxChooseRange();

                    Event.on("mousemove",boxChooseMove);
                }
            }

            // 结束框选
            let endBoxChoose = (e)=>{
                if(e.button == 0){
                    this.status.boxChoose = false;
                    boxChoose = false;
                    this.startTouch();
                    Event.off("mouseup",endBoxChoose);
                    this.figureData.selectData = selectData;
                    this.drawPreview();
                }

            }

            // 框选移动事件
            let boxChooseMove = (e)=>{
                if(!boxChoose){
                    return;
                }
                boxPoint.end = this.getMousePointToCanvas(e);
                if(Math.abs(boxPoint.end.x - boxPoint.start.x) < 5){
                    return;
                }
                if(!this.status.boxChoose){
                    Event.on("mouseup",endBoxChoose);
                    this.status.boxChoose = true;
                    this.stopTouch();
                }
                let parseBox = {
                    start:{},
                    end:{}
                }
                parseBox.start = this.toPoint(boxPoint.start,false);
                parseBox.end = this.toPoint(boxPoint.end,false);

                let maxX = parseBox.start.x >= parseBox.end.x ? parseBox.start.x : parseBox.end.x;
                let minX = parseBox.start.x < parseBox.end.x ? parseBox.start.x : parseBox.end.x;
                let maxY = parseBox.start.y >= parseBox.end.y ? parseBox.start.y : parseBox.end.y;
                let minY = parseBox.start.y < parseBox.end.y ? parseBox.start.y : parseBox.end.y;

                let boxRange = {
                    x:[minX,maxX],
                    y:[minY,maxY]
                }

                selectData = this.getInRangeImage(boxRange);

                var preImg = util.copyObject(selectData).map(img=>{
                    img.isPreview = true;
                    return img;
                });

                this.setPreview(preImg);

            };
            
            Event.on("click",closeBoxChoose);

            Event.on("mousedown",startBoxChoose);

            function closeBoxChoose(){
                boxChoose = false;

                self.status.boxChoose = false;

                Event.off("mousemove",boxChooseMove);

                Event.off("mouseup",endBoxChoose);
            }

            this.closeBoxChoose = closeBoxChoose;
        },

        // 关闭框选 在openBoxChoose中赋值
        closeBoxChoose(){},

        // 发送boxchoose消息
        sendBoxChooseRange(){
            var range = this.getImageRange(this.figureData.selectData,this.imgRecord.pads);

            range.x[0] = this.toReallyNumber(range.x[0],"x");
            range.x[1] = this.toReallyNumber(range.x[1],"x");
            range.y[0] = this.toReallyNumber(range.y[0],"y");
            range.y[1] = this.toReallyNumber(range.y[1],"y");

            if(this.imgConfig.mirror){
                let minX = range.x[0];
                range.x[0] = this.canvasSize[0] - range.x[1];
                range.x[1] = this.canvasSize[0] - minX;
            }

            Event.trigger("boxChoose",range);
        },

        getImageRange(imgList,pads){
            var allRange;
            var pinRange = {};
            imgList.forEach(img=>{
                var range = null;
                if(img.type == "pins"){
                    if(!pinRange[img.pinid]){
                        let pad = pads.find(pad=>pad.id == img.padid);
                        range = measureUtil.computedPinRange({x:img.data.x,y:img.data.y},pad);
                        pinRange[img.pinid] = range;
                    }else{
                        range = pinRange[img.pinid];
                    }
                }else{
                    range = measureUtil.computedImageRange(img);
                }
                // 判断图形是否有旋转
                if(img.data.rotate || img.data.pRotate){
                    let rotate = img.data.rotate;
                    if(img.data.pRotate){
                        rotate += img.data.pRotate;
                    }
                    let points = [
                        [range.x[1],range.y[0]],
                        [range.x[1],range.y[1]],
                        [range.x[0],range.y[0]],
                        [range.x[0],range.y[1]]
                    ];

                    let center = [(range.x[0] + range.x[1]) / 2, (range.y[0] + range.y[1]) / 2]

                    points = util.rotatePoints(points,center,rotate);

                    var maxX = points[0][0],maxY = points[0][1],minX = points[0][0],minY = points[0][1];
                    points.forEach(point=>{
                        if(maxX < point[0]){
                            maxX = point[0];
                        }
                        if(maxY < point[1]){
                            maxY = point[1];
                        }
                        if(minX > point[0]){
                            minX = point[0];
                        }
                        if(minY > point[1]){
                            minY = point[1];
                        }
                    });
                    range = {
                        x:[minX, maxX],
                        y:[minY, maxY]
                    }
                }
                allRange = measureUtil.compareRange(allRange,range);
            });
            if(!allRange){
                allRange = {x: [0, 0], y: [0, 0]};
            }
            return allRange;
        },

        // 旋转框选的图形
        rotateBoxChooseImage(type,center){
            var _rotateOriginData = util.copyObject(this.figureData.selectData);

            var _rotateAfertData = _rotateOriginData;

            var recordHistory = this._update("rotate");

            // 将图形抽离出来
            let imgIdList = this.figureData.selectData.map(img=>img.id);

            recordHistory.start(_rotateOriginData);

            this.extractToPreview(imgIdList);

            // 判断是否结束
            var isFinish = false;

            return {
                rotate:(rotate)=>{
                    if(isFinish){
                        return;
                    }
                    // 将数据进行抽离
                    if(this.figureData.selectData.length){
                        // 获取需要对齐的数据
                        // let pinIdList = [], imgIdList = []

                        let imgRange = {
                            pinRange:{},
                            imgRange:{},
                            allRange:null
                        }

                        _rotateAfertData = util.copyObject(_rotateOriginData).map(img=>{
                            if(type == 1){
                                if(img.type == "pins" || img.type == "texts" || (img.type == "path" && (img.form == "S" || img.form == "OC" || img.form == "OV"))){
                                    var rotatePoint = util.rotatePoint([img.data.x,img.data.y],[center.x,center.y],rotate);
                                    img.data.x = rotatePoint[0];
                                    img.data.y = rotatePoint[1];
                                    if(img.type == "pins"){
                                        img.data.pRotate += rotate;
                                    }else{
                                        img.data.rotate += rotate;
                                    }
                                }else if(img.type == "path"){
                                    img.data = rotateLineData(img.data,[center.x, center.y]);
                                }else{
                                    img.data.forEach((line,index)=>{
                                        img.data[index] = rotateLineData(line,[center.x, center.y]);
                                    });
                                }
                            }else if(type == 2){
                                if(img.type == "pins"){
                                    img.data.pRotate += rotate;
                                }else if(img.type == "texts" || (img.type == "path" && (img.form == "S" || img.form == "OC" || img.form == "OV"))){
                                    img.data.rotate += rotate;
                                }else if(img.type == "path"){
                                    img.data = rotateLineData(img.data);
                                }else{
                                    var shapeRange = measureUtil.getPathRange(img.data);
                                    var shapeCenter = [
                                        (shapeRange.x[0] + shapeRange.x[1]) / 2,
                                        (shapeRange.y[0] + shapeRange.y[1]) / 2
                                    ]
                                    img.data.forEach((line,index)=>{
                                        img.data[index] = rotateLineData(line,shapeCenter);
                                    });
                                }
                            }
                            return img;
                        });

                        this.figureData.selectData = util.copyObject(_rotateAfertData);

                        this.setPreview([]);

                        this.drawPreview();

                        // this.sendBoxChooseRange();

                        this.figureData.selectData.forEach(img=>{
                            img.isPreview = false;
                        });
                        
                        // recordHistory.finish(this.figureData.selectData);

                        this.layerDraw();

                        function rotateLineData(line,center){
                            var form = line.name.toUpperCase();
                            if(!center){
                                center = [0,0]
                                if(form == "LINE"){
                                    center[0] = (line.st_x + line.sp_x) / 2;
                                    center[1] = (line.st_y + line.sp_y) / 2;
                                }else{
                                    center[0] = line.o_x;
                                    center[1] = line.o_y;
                                }
                            }
                            var startPoint = util.rotatePoint([line.st_x,line.st_y],center,rotate);
                            var endPoint = util.rotatePoint([line.sp_x,line.sp_y],center,rotate);
                            line.st_x = startPoint[0];
                            line.st_y = startPoint[1];
                            line.sp_x = endPoint[0];
                            line.sp_y = endPoint[1];
                            if(form == "ARC"){
                                var  centerPoint = util.rotatePoint([line.o_x,line.o_y],center,rotate);
                                line.o_x = centerPoint[0];
                                line.o_y = centerPoint[1];
                            }
                            return line;
                        }
                    }
                },
                end:()=>{
                    Array(0).push.apply(this.figureData.imgDataTable,_rotateAfertData);
                    recordHistory.finish(_rotateAfertData);
                    isFinish = true;
                    this.layerDraw();
                }
            }
        }
    }

    // 选中图形的方法
    const selectMethods = {
        
        // 鼠标选中的图形
        pointsToImage(mouseSite){
            if(this.status.touch !== "run"){
                return;
            }

            let point = this.toPoint({
                x:mouseSite.x,
                y:mouseSite.y
            },false);

            if(this.status.pinCoord){
                let status = this.touchPinCoord(point);
                if(status) return;
            }

            this.touchImg(point);
            
        },

        touchPinCoord(point){
            if(!this.status.pinCoord){
                return;
            }

            let options = {
                oneFigure: true,
                useSelf: true
            };

            let imgList = this.getImageToPoint(point,this.temporaryData.pinCoordInfo.imgList,options)[0];

            this.temporaryData.pinCoordInfo.imgList.forEach(img=>{
                img.isPreview = false;
            });

            if(imgList){
                let pins = this.getImgList({pinIdList:imgList.pins});

                pins.forEach(img=>{
                    img.isPreview = true;
                });

                imgList.isPreview = true;

                if(imgList.bindFigure){
                    imgList.bindFigure.isPreview = true;
                }

                this.setPreview(pins); 
                return true;
            }else{
                this.setPreview([]);
            }

        },

        touchImg(point){

            let options = {};

            if(this.status.resetOrigin){
                options.onePin = true;
            }else if(this.status.measure){
                options.oneFigure = true;
            }

            let imgList = this.getImageToPoint(point,null,options);

            imgList.forEach(img=>{
                img.isPreview = "true";
            });

            this.returnTouch(imgList);
            this.setPreview(imgList,"touch"); 
        },

        // 获取指定位置下方的图形
        getImageToPoint(point,searchImgList,options){
            let selectImageId = [];
            let selectPinId = [];

            let selectImgs = [];

            var rotatePoints =  util.rotatePoints.bind(util);

            if(!searchImgList){
                searchImgList = this.figureData.drawOriginData;
            }
            // return [];

            // 是否在图形上策略
            var isInFigure = {
                pins:function(pin){
                        
                    let center = [
                        pin.data.x + pin.data.skewing_x,
                        pin.data.y + pin.data.skewing_y
                    ]
                    let flag = false;
                    if(pin.data.form === "C" || pin.data.form === "OC" || pin.data.form === "POLY"){
                        let imgData = {
                            x:center[0],
                            y:center[1],
                            r:pin.data.w
                        }
                        if(pin.data.form === "OC" || pin.data.form === "POLY"){
                            imgData.r = pin.data.r * 2;
                        }
                        flag = inCircle(point,imgData);
                    }else if(pin.data.form === "S" || pin.data.form === "CS" || pin.data.form === "OV"){
                        flag = inRect({
                            point,
                            center,
                            w:pin.data.w,
                            h:pin.data.h,
                            rotate:pin.data.rotate + pin.data.pRotate
                        });
                    }else if(pin.data.form === "PATH"){
                        let lines = [];
                        let arcs = [];
                        pin.data.path.forEach(line=>{
                            let form = line.name.toUpperCase();
                            lines.push([
                                center[0] + line.st_x,
                                center[1] + line.st_y
                            ]);
                            if(form === "ARC"){
                                arcs.push(line);
                            }
                        });
                        
                        if(pin.data.rotate || pin.data.pRotate){
                            lines = rotatePoints(lines,center,pin.data.rotate + pin.data.pRotate)
                        }
                        flag = inClosedShape(point,lines);
                    }
                    return flag;
                },
                path:function(path){
                    let flag = false;
                    path.form = path.form.toUpperCase();
                    if(path.form === "LINE"){
                        let lines = {
                            sp_x:path.data.sp_x,
                            sp_y:path.data.sp_y,
                            st_x:path.data.st_x,
                            st_y:path.data.st_y,
                            width:path.data.width
                        }
                        flag = inLine(point,lines);
                    }
                    if(path.form === "S"){
                        // let center = path.data.rotate?[path.data.o_x,path.data.o_y]:[path.x,path.y];
                        let center = [path.data.x,path.data.y];
                        let rotate = path.data.rotate;
                        let x = path.data.x, y = path.data.y;
                        let w = path.data.w,h = path.data.h;
                        let pointList = [[x - w/2,y - h/2],[x + w/2,y - h/2],[x + w/2, y + h/2],[x - w/2,y + h/2]];
                        if(rotate){
                            pointList = rotatePoints(pointList,center,rotate);
                        }
                        for(let i = 0, l = pointList.length; i < l; i++){
                            let linePoint1 = pointList[i];
                            let linePoint2 = i == l - 1 ? pointList[0] : pointList[i+1];
                            let line = {
                                st_x:linePoint1[0],
                                st_y:linePoint1[1],
                                sp_x:linePoint2[0],
                                sp_y:linePoint2[1],
                                width:path.data.width
                            }
                            if(inLine(point,line)){
                                flag = true;
                            }
                        }
                    }
                    if(path.form === "ARC"){
                        flag = inArc(point,path.data);
                    }
                    if(path.form === "OV"){
                        let lines =  toOriginMathods.ov2Path(path.data);
                        lines.forEach(line=>{
                            if(flag){
                                return;
                            }
                            if(line.name === "ARC"){
                                flag = inArc(point,line);
                            }else{
                                line.arc_r = line.arc_r === "nil";
                                flag = inLine(point,line);
                            }
                        });
                    }
                    return flag;
                },
                shapes:function(shape){
                    let form = shape.form.toUpperCase();
                    let flag = false;
                    if(form=="PATH"){
                        let lines = [];
                        shape.data.forEach(line=>{
                            lines.push([
                                line.st_x,
                                line.st_y
                            ]);
                        });
                        flag = inClosedShape(point,lines);
                    }
                    return flag;
                },
                texts:function(text){
                    let center = [
                        text.data.x,
                        text.data.y
                    ];
                    let flag = inRect({
                        point,
                        center,
                        w:text.data.textwidth,
                        h:text.data.textheight,
                        rotate:text.data.rotate
                    });
                    return flag;
                }
            }

            searchImgList.forEach(figure=>{
                var flag = isInFigure[figure.type](figure);
                if(flag){
                    if(figure.type == "pins"){
                        if(options.useSelf){
                            selectImgs.push(figure);
                        }else{
                            selectPinId.push(figure.pinid);
                        }
                    }else{
                        if(options.useSelf){
                            selectImgs.push(figure);
                        }else{
                            selectImageId.push(figure.id);
                        }
                    }
                }
            });
    
            let imgList = [];
            if(options){

                if(options.useSelf){
                    return selectImgs;
                }
                if(options.onlyPin){
                    return imgList = this.getImgList({pinIdList:selectPinId});
                }
                if(options.onePin){
                    return imgList = this.getImgList({pinIdList:[selectPinId[0]]});
                }
                if(options.oneFigure){
                    if(selectPinId.length){
                        return imgList = this.getImgList({pinIdList:[selectPinId[0]]});
                    }else{
                        return imgList = this.getImgList({imgIdList:[selectImageId[0]]});
                    }
                }
            }
            return imgList = this.getImgList({pinIdList:selectPinId,imgIdList:selectImageId},searchImgList);
            
            // 是否在矩形内
            function inRect({point,center,w,h,rotate}){
                let lines = [];
                lines.push([
                    center[0] + w / 2,
                    center[1] + h / 2
                ]);
                lines.push([
                    center[0] + w / 2,
                    center[1] - h / 2
                ]);
                lines.push([
                    center[0] - w / 2,
                    center[1] - h / 2
                ]);
                lines.push([
                    center[0] - w / 2,
                    center[1] + h / 2
                ]);
                if(rotate){
                    lines = util.rotatePoints(lines,center,rotate);
                }
                return inClosedShape(point,lines);
            }

            // 是否在线上
            function inLine(point,line){
                // 计算线条的斜率
                let rectData = []
                if(line.st_x == line.sp_x || line.st_y == line.sp_y){
                    rectData.push([
                        line.st_x + line.width / 2,
                        line.st_y + line.width / 2
                    ]);
                    rectData.push([
                        line.sp_x + line.width / 2,
                        line.sp_y + line.width / 2
                    ]);
                    rectData.push([
                        line.sp_x - line.width / 2,
                        line.sp_y - line.width / 2
                    ]);
                    rectData.push([
                        line.st_x - line.width / 2,
                        line.st_y - line.width / 2
                    ]);
                }else{
                    let k = (line.st_y - line.sp_y) / (line.st_x - line.sp_x);
                    let slope = -1/k;
                    // x = x1±Math.sqrt(d/(k^2+1));
                    let base = Math.sqrt(Math.pow(line.width / 2,2) / (slope * slope + 1));
                    let point1 = [
                        line.st_x + base,
                        base * slope + line.st_y,
                    ]
                    let point2 = [
                        line.st_x - base,
                        -base * slope + line.st_y,
                    ]
                    let point3 = [
                        base + line.sp_x,
                        base * slope + line.sp_y,
                    ]
                    let point4 = [
                        line.sp_x - base,
                        -base * slope + line.sp_y,
                    ]
                    rectData.push(point1);
                    rectData.push(point3);
                    rectData.push(point4);
                    rectData.push(point2);
                }
                return inClosedShape(point,rectData);
            }

            function inArc(point,arc){
                let x = point.x,y = -point.y;
                let status=false,
                    r=arc.r,
                    st_x=arc.st_x,
                    st_y=-arc.st_y,
                    sp_x=arc.sp_x,
                    sp_y=-arc.sp_y,
                    line_w=arc.width/2,
                    o_x=arc.o_x,
                    o_y=-arc.o_y,
                    dir=arc.arc_r,
                    rot = arc.rotate;
                let gap=Math.sqrt((Math.pow(x-o_x,2)+Math.pow(y-o_y,2)));
                if(r-line_w<gap&&gap<r+line_w){//满足圆的方程
                    let median=sountAngle(x-o_x ,  y-o_y),
                        st = sountAngle(st_x-o_x, st_y-o_y),
                        sp = sountAngle(sp_x-o_x, sp_y-o_y);
                    //计算夹角
                    let angle_ref=[],
                        angle_acc=[],
                        angle_st=180*st.angle/Math.PI,
                        angle_me=180*median.angle/Math.PI,
                        angle_sp=180*sp.angle/Math.PI;
                    angle_ref=[angle_st,angle_sp];
                    let maxAngle=Math.max.apply(null,angle_ref),
                        minAngle=Math.min.apply(null,angle_ref);
                    if(st_x==sp_x&&st_y==sp_y){
                        status=true;
                    }else{
                        //判断夹角是否过0点
                        let angle_lock=false,
                            qua_st=st.qua,
                            qua_sp=sp.qua;
                        if(dir === "t"){//顺时针
                            if(qua_st==1&&qua_sp==2||qua_st==1&&qua_sp==3
                                ||qua_st==1&&qua_sp==4||qua_st==2&&qua_sp==3
                                ||qua_st==2&&qua_sp==4||qua_st==3&&qua_sp==4
                                ){
                                angle_lock=true;
                            }else if(qua_st==1&&qua_sp==1
                                ||qua_st==4&&qua_sp==4){
                                if(st_y<sp_y){
                                    angle_lock=true;
                                }
                            }else if(qua_st==2&&qua_sp==2
                                ||qua_st==3&&qua_sp==3){
                                if(st_y>sp_y){
                                    angle_lock=true;
                                }
                            }
                        }else{//逆时针
                            if(qua_st==2&&qua_sp==1||qua_st==3&&qua_sp==1
                            ||qua_st==3&&qua_sp==2||qua_st==4&&qua_sp==1
                            ||qua_st==4&&qua_sp==2||qua_st==4&&qua_sp==3){
                                angle_lock=true;
                            }else if(qua_st==1&&qua_sp==1
                                ||qua_st==4&&qua_sp==4){
                                if(st_y>sp_y){
                                    angle_lock=true;
                                }
                            }else if(qua_st==2&&qua_sp==2
                                ||qua_st==3&&qua_sp==3){
                                if(st_y<sp_y){
                                    angle_lock=true;
                                }
                            }
                        }
                        if(angle_lock){
                            if(minAngle<angle_me&&angle_me<maxAngle){
                                status=true;
                            }
                        }else{
                            
                            if(minAngle>=angle_me||angle_me>maxAngle){
                                status=true;
                            }
                        }
                    }
                }
                return status;
            }

            function sountAngle(x,y){
                var angle=0,
                    qua=0;
                if(x>0&&y>=0){
                    angle=Math.atan(y/x);
                    qua=1;
                }else if(x<=0&&y>0){
                    x=Math.abs(x);
                    angle=Math.atan(x/y)+0.5*Math.PI;
                    qua=2;
                }else if(x<0&&y<=0){
                    x=Math.abs(x);
                    y=Math.abs(y);
                    angle=Math.atan(y/x)+Math.PI;
                    qua=3;
                }else if(x>=0&&y<0){
                    y=Math.abs(y);
                    angle=Math.atan(x/y)+1.5*Math.PI;
                    qua=4;
                }
                return {
                    angle:angle,
                    qua:qua,
                };
            
            }

            // 判断图形是否在一封闭图形内
            function inClosedShape(point,line){
                var inside = false;
                for(let i = 0,l = line.length; i < l ; i++){
                    let linePoint1 = line[i];
                    let linePoint2 = i == l - 1 ? line[0] : line[i+1];
                    let slope = (linePoint2[1] - linePoint1[1]) / (linePoint2[0] - linePoint1[0]);
                    // 判断点是否在线段的x轴之间
                    let betweenX = (linePoint1[0] < point.x && linePoint2[0] > point.x) || (linePoint1[0] > point.x && linePoint2[0] < point.x);
                    // 以point作一条平行于Y轴的射线，判断射线与经过linePoint1和linePoint2两点的直线的交点,是否位于point的y轴的上方
                    let intersect = point.y < (slope * (point.x - linePoint1[0]) + linePoint1[1]);
                    
                    if(betweenX && intersect){
                        inside = !inside;
                    }
                }
                return inside;
            }

            // 是否在圆内
            function inCircle(point,img){
                let dis = Math.sqrt(Math.pow(point.x - img.x,2) + Math.pow(point.y - img.y,2));
                return dis <= img.r/2;
            }
        },
        
        // 暂停选择图形
        pauseTouch(info){
            this.status.touch = "pause";
            this.hook && this.hook.pauseTouch && this.hook.pauseTouch();
        },

        // 停止选图形
        stopTouch(info){
            if(info){
                console.log(info);
            }
            this.status.touch = "stop";
            this.hook && this.hook.stopTouch && this.hook.stopTouch();
            this.returnTouch([]);
        },

        // 开始选图形
        startTouch(){
            if(this.status.insert){
                return;
            }
            this.status.touch = "run";
            this.hook && this.hook.startTouch && this.hook.startTouch();
            this.returnTouch([]);
        },

        getInRangeImage(range){
            let selectFigureID = {
                imgIdList:[],
                pinIdList:[]
            }
            this.figureData.drawOriginData.forEach(figure=>{
                let inRange = figureComputed.figureInTheRange(figure,range);
                if(inRange){
                    if(figure.type == "pins"){
                        selectFigureID.pinIdList.push(figure.pinid);
                    }else{
                        selectFigureID.imgIdList.push(figure.id);
                    }
                }
            });

            return this.getImgList(selectFigureID);
        },

        // 高亮pad
        highlightPad(padid){
            let pinList = this.getPinsByPadId(padid);
            pinList.forEach(pin=>{
                pin.isPreview = true;
            })
            this.setPreview(pinList,"touch");
        }
    }

    // 编辑所用到的方法
    /**
     * @this DrawEncapsulation
     */
    const editEncaMethods = {

        // 通过编号获取图形数据
        getImgList(imgIdObj,searchImgList){
            let pinIdList = imgIdObj.pinIdList || [];
            let imgIdList = imgIdObj.imgIdList || [];

            pinIdList = [...new Set(pinIdList)];
            imgIdList = [...new Set(imgIdList)];

            let pinList = this.getPinsByIds(pinIdList,searchImgList);
            let imgList = this.getImgsByIds(imgIdList,searchImgList);


            [].push.apply(imgList,pinList);

            return imgList;
        },

        // 通过图形id获取图形
        getImgsByIds(imgIdList,searchImgList){
            let imgList = [];
            if(!searchImgList){
                searchImgList = this.figureData.imgDataTable;
            }
            searchImgList.forEach(img=>{
                if(imgIdList.findIndex((id)=>id===img.id)!== -1){
                    imgList.push(util.copyObject(img));
                }
            });
            return imgList;
        },

        // 通过pinid获取pin
        getPinsByIds(pinIdList,searchImgList){
            pinIdList = [...new Set(pinIdList)];
            let pinListObj = {};

            pinIdList.forEach(pinid=>pinListObj[pinid] = []);

            if(!searchImgList){
                searchImgList = this.figureData.imgDataTable;
            }

            searchImgList.forEach(img=>{
                if(img.type==="pins" && pinListObj[img.pinid]){
                    pinListObj[img.pinid].push(util.copyObject(img));
                }
            });

            let pinList = [];

            Object.getOwnPropertyNames(pinListObj).forEach(key=>{
                [].push.apply(pinList,pinListObj[key])
            });
            
            return pinList;
        },

        // 通过padid获取pin
        getPinsByPadId(padId){
            let pinListObj = {};
            this.figureData.imgDataTable.forEach(img=>{
                if(img.type==="pins" && img.padid == padId){
                    if(!pinListObj[img.pinid]){
                        pinListObj[img.pinid] = [];
                    }
                    pinListObj[img.pinid].push(util.copyObject(img));
                }
            });
            let pinList = [];
            Object.getOwnPropertyNames(pinListObj).forEach(key=>{
                [].push.apply(pinList,pinListObj[key]);
            });
            
            return pinList;
        },

        // 将选中的图形返回
        returnTouch(touchImgList){
            let imgList = [];
            let pinIdList = [];
            touchImgList.forEach(img=>{
                if(img.type === "pins"){
                    pinIdList.push(img.pinid);
                }else{
                    imgList.push(img);
                }
            });

            [].push.apply(imgList,getPinsByPinId(pinIdList,touchImgList));

            this.hook?.touch?.(imgList);

            // 通过pinid获取pin
            function getPinsByPinId(pinIdList,touchImgList){
                let pinListObj = {},pinList = [];
                
                pinIdList = [...new Set(pinIdList)];

                pinIdList.forEach(pinid=>pinListObj[pinid] = {
                    pinid,
                    type:"pins",
                    pin_num:"",
                    data:[]
                });

                touchImgList.forEach(img=>{
                    if(img.type==="pins" && pinListObj[img.pinid]){
                        pinListObj[img.pinid].x = img.data.x;
                        pinListObj[img.pinid].y = img.data.y;
                        pinListObj[img.pinid].pin_num = img.pin_num;
                        pinListObj[img.pinid].padid = img.padid;
                        pinListObj[img.pinid].data.push(img);
                    }
                });

                Object.getOwnPropertyNames(pinListObj).forEach(key=>{
                    pinList.push(pinListObj[key]);
                });

                return pinList;
            }
        },

        // 编辑指定id的数据
        editList(editInfo){
            // 获取所有的pin
            // let pinList = this.getPinsByPinId(editInfo.pinIdList);
            let imgIdList = editInfo.imgIdList || [];

            let pins = this.getPinsByIds(editInfo.pinIdList || []);

            let imgList = this.getImgList(editInfo);

            Array(0).push.apply(imgIdList,pins.map(pin_layer=>pin_layer.id));

            this.extractToPreview(imgIdList);
            this.status.edit = true;
            this.stopTouch("编辑暂停");

            this.__updateRecord = this._update("edit");

            this.figureData.editData = util.copyObject(this.handleEditData(imgList));

            this.__updateRecord.start({
                imgList,
                config:this.figureData.editData.config,
                pad:this.figureData.editData.pad
            });

            return util.copyObject(this.figureData.editData);
        },

        // 编辑pin
        editPin(pinIds){
            let self = this;
            let pins = this.getPinsByIds(pinIds);
            if(pins){
                // 获取该pin每一层对应的图形id
                let imgIdList = pins.map(pin_layer=>pin_layer.id);

                this.extractToPreview(imgIdList);
                this.status.edit = true;
                this.stopTouch();
                this.figureData.editData = util.copyObject(this.handleEditData(pins));

                this.__updateRecord = this._update("edit");

                this.__updateRecord.start({
                    imgList:pins,
                    config:this.figureData.editData.config,
                    pad:this.figureData.editData.pad
                });

                return util.copyObject(this.figureData.editData);
            }
        },

        // 编辑相同的pin
        editSamePin(padId){
            let pins = this.getPinsByPadId(padId);
            if(pins){
                // 获取该pin每一层对应的图形id
                let imgIdList = pins.map(pin_layer=>pin_layer.id);
                this.extractToPreview(imgIdList);
                this.status.edit = true;
                this.stopTouch();
                this.figureData.editData = util.copyObject(this.handleEditData(pins));

                this.__updateRecord = this._update("edit");

                this.__updateRecord.start({
                    imgList:pins,
                    config:this.figureData.editData.config,
                    pad:this.figureData.editData.pad
                });

                return util.copyObject(this.figureData.editData);
            }
        },
        
        // 返回可以编辑的数据
        handleEditData(imageList){
            let editData = {
                type:"",
                config:{
                    // 是否可以编辑pin
                    editPin:false,
                    // 是否可以编辑pad
                    editPad:false,
                    // 是否可以编辑路径
                    editPath:false,
                    // 是否可以编辑文字
                    editTexts:false,
                    // 是否可以编辑铜皮
                    editShapes:false,
                    // 是否可以编辑图形属性
                    editImage:false,
                    // 是否可以整体移动
                    allowMove:false,
                },
                pins:[],
                originPins:[],
                path:[],
                originPath:[],
                shapes:[],
                originShapes:[],
                texts:[],
                originTexts:[],
                pad:{},
                imgs:[]
            };

            let pins = [],path = [],shapes = [], texts = [];

            imageList.forEach(figure=>{
                if(figure.type === "pins"){
                    pins.push(figure);
                }else if(figure.type === "path"){
                    path.push(figure);
                }else if(figure.type === "shapes"){
                    shapes.push(figure);
                }
                else{
                    texts.push(figure);
                }
            });

            let typeCount = 0;
            if(path.length){
                editData.path = path;
                editData.originPath = util.copyObject(path);
                editData.type = "path";
                typeCount++;
                if(path.length == 1){
                    editData.config.editPath = true;
                }
            }

            if(shapes.length){
                editData.shapes = shapes;
                editData.originShapes = util.copyObject(shapes);
                editData.type = "shapes";
                typeCount++;
                if(shapes.length == 1){
                    editData.config.editShapes = true;
                }
            }

            if(texts.length){
                editData.texts = texts;
                editData.originTexts = util.copyObject(texts);
                editData.type = "texts";
                typeCount++;
                if(texts.length == 1){
                    editData.config.editTexts = true;
                }
            }

            if(pins.length){
                let padIds = new Set();
                editData.config.editPin = true;
                editData.type = "pins";
                editData.pins = toOriginMathods.toOriginPins(pins);
                editData.originPins = util.copyObject(editData.pins);
                typeCount++;

                if(editData.pins.length > 1){
                    editData.config.allowMove = true;
                    editData.config.editPin = false;
                }
                
                editData.pins.forEach(pin=>{
                    padIds.add(pin.padid);
                });

                if(padIds.size === 1){
                    let padId = [...padIds][0];
                    editData.config.editPad = true;
                    editData.pad = this.imgRecord.pads.find((pad)=>pad.id === padId);
                    if(!editData.pad){
                        console.log(util.copyObject(this.imgRecord.pads),padIds,padId);
                        console.error("出错了")
                    }
                }
            }

            if(typeCount>1){
                editData.type = "move";
                editData.config.editPad = false;
                editData.config.editPin = false;
                editData.config.allowMove = true;
                editData.config.editImage = false;
            }

            // console.log(editData)

            return editData;
        },

        // 修改pad的某一层
        editPadLayer(editData){
            this.figureData.editData.editedPad = true;
            if(editData.type == "delete"){
                if(editData.layer=="drill"){
                    this.figureData.editData.pad.drill.splice(editData.drill_index,1);
                }else{
                    this.figureData.editData.pad[editData.layer] = {};
                }
                let pins = util.copyObject(this.figureData.editData.pins);
                let pads = util.copyObject([this.figureData.editData.pad]);
                let previewImage = handleUtil.handlerPinDraw(pins,pads);
                previewImage.forEach(img=>{
                    img.isPreview = true;
                });
                // 更新演示层数据
                this.setPreview(previewImage);
                return;
            }
            if(!this.status.edit){
                return;
            }
            if(editData.layer!="drill"){
                var layerData = this.figureData.editData.pad[editData.layer] || {};
            }else{
                var layerData = this.figureData.editData.pad.drill[editData.drill_index] || {}
            }
            let data = util.copyObject(editData.data);
            layerData.r = parseFloat(data.r) || 0;
            layerData.skewing_x = parseFloat(data.skewing_x) || 0;
            layerData.skewing_y = parseFloat(data.skewing_y) || 0;
            layerData.rotate = parseFloat(data.rotate) || 0;
            layerData.w = parseFloat(data.w) || 0;
            layerData.h = parseFloat(data.h) || 0;
            layerData.form = data.form;
            if(layerData.form=="C"){
                layerData.h = layerData.w;
                layerData.r = layerData.w/2;
            }
            if(editData.layer!="drill"){
                this.figureData.editData.pad[editData.layer] = layerData;
            }else{
                this.figureData.editData.pad.drill[editData.drill_index] = layerData;
            }
            // console.log(layerData)
            let pins = util.copyObject(this.figureData.editData.pins);
            let pads = util.copyObject([this.figureData.editData.pad]);
            let previewImage = handleUtil.handlerPinDraw(pins,pads);
            previewImage.forEach(img=>{
                img.isPreview = true;
            });
            // 更新演示层数据
            this.setPreview(previewImage);
        },

        // 修改正在编辑的pin
        updatePinData(newPin){
            if(this.figureData.editData.config.editPin){
                this.figureData.editData.pins.forEach(pin=>{
                    pin.pin_num = newPin.pin_num;
                    pin.x = newPin.x;
                    pin.y = newPin.y;
                    pin.rotate = newPin.rotate;
                });
                let pins = util.copyObject(this.figureData.editData.pins);
                let pads = util.copyObject([this.figureData.editData.pad]);
                let previewImage = handleUtil.handlerPinDraw(pins,pads);
                previewImage.forEach(img=>{
                    img.isPreview = true;
                });
                // 更新演示层数据
                this.setPreview(previewImage);
            }
        },

        updateImages(updateData){
            updateData = util.copyObject(updateData);
            if(this.status.edit){
                let editData = this.figureData.editData;
                if(editData.type == "path"){
                    if(editData.config.editPath){
                        let line = editData.path[0];
                        if(line.layer){
                            line.layer = updateData.layer;
                        }
                        if(line.form == "ARC"){
                            let diffOX =  line.data.o_x - updateData.data.o_x;
                            let diffOY =  line.data.o_y - updateData.data.o_y;
                            line.data.o_x = updateData.data.o_x;
                            line.data.o_y = updateData.data.o_y;
                            line.data.width = updateData.data.width;
                            line.data.st_x -= diffOX;
                            line.data.st_y -= diffOY;
                            line.data.sp_x -= diffOX;
                            line.data.sp_y -= diffOY;
                            // line.data = util.computedArc(updateData.data);
                        }else{
                            line.data = {
                                ...updateData.data
                            }
                        }
                        editData.path[0] = line;
                    }
                }
                if(editData.type == "shapes"){
                    let shapes = util.copyObject(editData.originShapes);
                    shapes.forEach(shape=>{
                        if(updateData.layer){
                            shape.layer = updateData.layer;
                        }
                        shape.data.forEach(path=>{
                            path.st_x += updateData.x;
                            path.st_y += updateData.y;
                            path.sp_x += updateData.x;
                            path.sp_y += updateData.y;
                            if(path.name == "ARC"){
                                path.o_x += updateData.x;
                                path.o_y += updateData.y;
                            }
                        });
                    });
                    editData.shapes = shapes;
                }
                if(editData.type == "texts"){
                    if(editData.config.editTexts){
                        let text = editData.texts[0];
                        text.layer = updateData.layer;
                        text.data.content = updateData.data.content;
                        text.data.rotate = updateData.data.rotate;
                        text.data.textblock = updateData.data.textblock;
                        text.data.x = updateData.data.x;
                        text.data.y = updateData.data.y;
                        text.data.textheight = text.data.textblock;
                        text.data.textwidth = text.data.textblock * text.data.content.length;
                    }
                }
            }
            this._showUpdateImage();
        },

        _showUpdateImage(){
            let previewImage = this._getNowEditImages();
            previewImage.forEach(img=>{
                img.isPreview = true;
            });
            // 更新演示层数据
            this.setPreview(previewImage);
        },

        _getNowEditImages(){
            let previewImage = [];
            let editData = util.copyObject(this.figureData.editData);

            if(editData.pins.length){
                let pins = util.copyObject(this.figureData.editData.pins);
                let pads = [];
                if(editData.config.editPad && editData.editedPad){
                    pads = util.copyObject(editData.pads);
                }else{
                    pads = util.copyObject(this.imgRecord.pads);
                }
                previewImage.push(...handleUtil.handlerPinDraw(pins,pads));
            }

            previewImage.push(...editData.path,...editData.shapes,...editData.texts);
            return previewImage;
        },

        // 退出并保存编辑
        saveEdit(){
            if(!this.status.edit){
                return;
            }
            this.status.edit = false;
            let imgList = [];
            let editData = this.figureData.editData;
            if(editData.config.editPad){
                if(editData.editedPad){
                    let h_type,p_type;
                    if(editData.pad.drill.length>0){
                        h_type=true;
                    }else{
                        h_type=false;
                    }
                    if(editData.pad.t.form){
                        p_type=true;
                    }else if(editData.pad.b.form){
                        p_type=true;
                    }else{
                        p_type=false;
                    }
                    let kind = "";
                    if(h_type&&p_type){
                        kind="via";
                    }else if(!h_type&&p_type){
                        kind="smt";
                    }else if(h_type&&!p_type){
                        kind="hole";
                    }
                    editData.pad.kind = kind;

                    editData.pad.id = this.imgRecord.pads_id + 1;

                    editData.pins.forEach(pin=>{
                        pin.padid = editData.pad.id;
                        pin.kind = kind;
                    });
                }
                let pins = util.copyObject(editData.pins);

                let pads = util.copyObject([editData.pad]);

                imgList = handleUtil.handlerPinDraw(pins,pads);

                imgList.forEach(img=>{
                    img.id = ++this.imgRecord.countId;
                });
            }else{
                imgList = this._getNowEditImages();
            }

            this.__updateRecord.finish({
                imgList,
                editedPad:editData.editedPad,
                pad:this.figureData.editData.pad
            });

            this.__updateRecord = null;

            this.startTouch();
            this.setPreview([]);
            imgList.forEach(img=>{
                delete img.isPreview;
            });
            [].push.apply(this.figureData.imgDataTable,imgList);

            if(editData.editedPad){
                this.addPads([editData.pad]);
            }
            // this.closeMoveSelectImage();
            this.layerDraw();
        },

        // 抽离绘制的图形到显示层
        extractToPreview(imgIdList){
            let imgList = [];
            for(let i = 0,l = this.figureData.imgDataTable.length; i < l; i++){
                let img = this.figureData.imgDataTable[i];
                if(imgIdList.indexOf(img.id) !== -1){
                    imgList.push(this.figureData.imgDataTable.splice(i,1)[0]);
                    l--;
                    i--;
                }
            }
            imgList.forEach(img=>{
                img.isPreview = true;
            });
            this.setPreview(imgList);
            this.layerDraw();
        },

        // 设置演示层数据
        setPreview(imgList){
            this.figureData.previewData = imgList;
            this.drawPreview();
        },

        // 绘制演示层
        drawPreview(){
            let drawOriginData = util.copyObject(this.figureData.previewData);
            if(this.status.measure){
                [].push.apply(drawOriginData,this.figureData.measureData.startImages || []);
                [].push.apply(drawOriginData,this.figureData.measureData.endImages || []);
            }
            if(this.status.resetOrigin && this.figureData.resetOriginData.selectStart){
                [].push.apply(drawOriginData,this.figureData.resetOriginData.startImage || []);
            }
            let selectData = util.copyObject(this.figureData.selectData) || [];
            if(selectData.length){
                selectData.forEach(figure=>{
                    figure.isPreview = true;
                });
                Array(0).push.apply(drawOriginData,selectData);
            }
            if(this.status.mirrorCopy){
                Array(0).push.apply(drawOriginData,this.temporaryData.mirrorCopyData);
            }
            if(this.status.pinCoord){
                drawOriginData.push(...this.temporaryData.pinCoordInfo.imgList);
            }
            this.sendBoxChooseRange();
            this.drawImage.preview = this.transformDrawImage(drawOriginData);
            this.drawObj.drawPreview.clear();
            this.drawObj.drawPreview.redrawAll(util.copyObject(this.drawImage.preview));
        },

        // 重新设置原点
        resetOrigin(){
            this.resetStatus();
            this.status.resetOrigin = true;
            let startPoint = {
                x:0,
                y:0
            }
            this.canvasParent.onclick = (e)=>{

                let movePoint = {
                    x:0,
                    y:0
                };
                
                // 如果有预选图形将其记录
                if(this.figureData.previewData.length){
                    this.figureData.resetOriginData.startImage = util.copyObject(this.figureData.previewData);
                    movePoint.x = this.figureData.resetOriginData.startImage[0].data.x;
                    movePoint.y = this.figureData.resetOriginData.startImage[0].data.y;
                    if(e.ctrlKey){
                        this.figureData.resetOriginData.selectStart = !this.figureData.resetOriginData.selectStart;
                        if(this.figureData.resetOriginData.selectStart){
                            startPoint.x = movePoint.x;
                            startPoint.y = movePoint.y;
                        }else{
                            movePoint.x = (movePoint.x + startPoint.x) / 2;
                            movePoint.y = (movePoint.y + startPoint.y) / 2;
                            this.figureData.resetOriginData.startImage = [];
                            this.figureData.resetOriginData.selectStart = false;
                        }
                    }else{
                        this.figureData.resetOriginData.selectStart = false;
                        this.figureData.resetOriginData.startImage = [];
                    }
                }else{
                    this.figureData.resetOriginData.selectStart = false;
                    this.figureData.resetOriginData.startImage = [];
                    movePoint = this.toPoint(this.getMousePointToCanvas(e))
                }                

                this.drawPreview();

                // 等待250ms确认是单击
                setTimeout(()=>{
                    if(this.status.resetOrigin){
                        if(!this.figureData.resetOriginData.selectStart){
                            this._resetOrigin(movePoint);
                            this._update("resetOrigin").finish(movePoint);
                            this.layerDraw();
                        }
                    }
                },250);
                
            }
        },

        _resetOrigin(movePoint){
            let origin = util.copyObject(this.origin);
            let scale = this.imgConfig.units ==="mm"?this.scale * 39.37 : this.scale;
            
            let offset = {
                x:movePoint.x * scale,
                y:movePoint.y * scale
            };
            origin = {
                x:origin.x + offset.x,
                y:origin.y - offset.y
            }
            this.figureData.imgDataTable = handleUtil.changeEncaOrigin(this.figureData.imgDataTable,movePoint);
            this.setOrigin(origin,false);
        },

        // 结束原点设置
        finishSetOrigin(){
            this.status.resetOrigin = false;
            this.canvasParent.onclick = null;
        },

        // 对齐图形
        align(type){
            var alignStrategys = {
                top:function(imgList,imgRange){
                    if(!imgList) return [];
                    imgList.forEach(img=>{
                        if(img.type == "pins"){
                            // 获取pin的范围
                            let range = imgRange.pinRange[img.pinid];
                            // 计算向上移动的距离
                            let topMove = imgRange.allRange.y[1] - range.y[1];
                            img.data.y += topMove;
                            return;
                        }else{
                            let range = imgRange.imgRange[img.id];
                            let move = imgRange.allRange.y[1] - range.y[1];
                            if(img.type == "path"){
                                img.data = movePath(img.data, move);
                                return;
                            }
                            if(img.type == "shapes"){
                                img.data.forEach((item,index)=>{
                                    img.data[index] = movePath(item, move);
                                });
                                return;
                            }
                            if(img.type == "texts"){
                                img.data.y += move;
                                return;
                            }
                        }
                    });

                    function movePath(data, move){
                        if(data.name == "ARC" || data.name == "LINE"){
                            data.st_y += move;
                            data.sp_y += move;
                            if(data.name == "ARC"){
                                data.o_y += move;
                            }
                        }else{
                            data.y += move;
                        }
                        return data;
                    }

                    return imgList;
                },
                bottom:function(imgList,imgRange){
                    if(!imgList) return [];
                    imgList.forEach(img=>{
                        if(img.type == "pins"){
                            // 获取pin的范围
                            let range = imgRange.pinRange[img.pinid];
                            // 计算向上移动的距离
                            let topMove = imgRange.allRange.y[0] - range.y[0];
                            img.data.y += topMove;
                            return;
                        }else{
                            let range = imgRange.imgRange[img.id];
                            let move = imgRange.allRange.y[0] - range.y[0];
                            if(img.type == "path"){
                                img.data = movePath(img.data, move);
                                return;
                            }
                            if(img.type == "shapes"){
                                img.data.forEach((item,index)=>{
                                    img.data[index] = movePath(item,move);
                                });
                                return;
                            }
                            if(img.type == "texts"){
                                img.data.y += move;
                                return;
                            }
                        }
                    });

                    function movePath(data, move){
                        if(data.name == "ARC" || data.name == "LINE"){
                            data.st_y += move;
                            data.sp_y += move;
                            if(data.name == "ARC"){
                                data.o_y += move;
                            }
                        }else{
                            data.y += move;
                        }
                        return data;
                    }

                    return imgList;
                },
                left:function(imgList,imgRange){
                    if(!imgList) return [];
                    imgList.forEach(img=>{
                        if(img.type == "pins"){
                            // 获取pin的范围
                            let range = imgRange.pinRange[img.pinid];
                            // 计算向上移动的距离
                            let topMove = imgRange.allRange.x[0] - range.x[0];
                            img.data.x += topMove;
                            return;
                        }else{
                            let range = imgRange.imgRange[img.id];
                            let move = imgRange.allRange.x[0] - range.x[0];
                            if(img.type == "path"){
                                img.data = movePath(img.data,move);
                                return;
                            }
                            if(img.type == "shapes"){
                                img.data.forEach((item,index)=>{
                                    img.data[index] = movePath(item,move);
                                });
                                return;
                            }
                            if(img.type == "texts"){
                                img.data.x += move;
                                return;
                            }
                        }
                    });

                    function movePath(data, move){
                        if(data.name == "ARC" || data.name == "LINE"){
                            data.st_x += move;
                            data.sp_x += move;
                            if(data.name == "ARC"){
                                data.o_x += move;
                            }
                        }else{
                            data.x += move;
                        }
                        return data;
                    }
                    return imgList;
                },
                right:function(imgList,imgRange){
                    if(!imgList) return [];
                    imgList.forEach(img=>{
                        if(img.type == "pins"){
                            // 获取pin的范围
                            let range = imgRange.pinRange[img.pinid];
                            // 计算向上移动的距离
                            let move = imgRange.allRange.x[1] - range.x[1];
                            img.data.x += move;
                            return;
                        }else{
                            let range = imgRange.imgRange[img.id];
                            let move = imgRange.allRange.x[1] - range.x[1];
                            if(img.type == "path"){
                                img.data = movePath(img.data, move)
                                return;
                            }
                            if(img.type == "shapes"){
                                img.data.forEach((item,index)=>{
                                    img.data[index] = movePath(item,move);
                                });
                                return;
                            }
                            if(img.type == "texts"){
                                img.data.x += move;
                                return;
                            }
                        }
                    });

                    function movePath(data, move){
                        if(data.name == "ARC" || data.name == "LINE"){
                            data.st_x += move;
                            data.sp_x += move;
                            if(data.name == "ARC"){
                                data.o_x += move;
                            }
                        }else{
                            data.x += move;
                        }
                        return data;
                    }

                    return imgList;
                },
                horizontal:function(imgList,imgRange){
                    if(!imgList) return [];
                    imgList.forEach(img=>{
                        if(img.type == "pins"){
                            // 获取pin的范围
                            let range = imgRange.pinRange[img.pinid];
                            // 计算向上移动的距离
                            let topMove = (imgRange.allRange.y[0] + imgRange.allRange.y[1])/2 - img.data.y;
                            img.data.y += topMove;
                            return;
                        }else{
                            let range = imgRange.imgRange[img.id];
                            let move = (imgRange.allRange.y[0] + imgRange.allRange.y[1])/2 - (range.y[0] + range.y[1]) / 2;
                            if(img.type == "path"){
                                img.data = movePath(img.data, move)
                                return;
                            }
                            if(img.type == "shapes"){
                                img.data.forEach((item,index)=>{
                                    img.data[index] = movePath(item,move);
                                });
                                return;
                            }
                            if(img.type == "texts"){
                                img.data.y += move;
                                return;
                            }
                        }
                    });

                    function movePath(data, move){
                        if(data.name == "ARC" || data.name == "LINE"){
                            data.st_y += move;
                            data.sp_y += move;
                            if(data.name == "ARC"){
                                data.o_y += move;
                            }
                        }else{
                            data.y += move;
                        }
                        return data;
                    }

                    return imgList;
                },
                vertical:function(imgList,imgRange){
                    if(!imgList) return [];
                    imgList.forEach(img=>{
                        if(img.type == "pins"){
                            // 获取pin的范围
                            let range = imgRange.pinRange[img.pinid];
                            // 计算向上移动的距离
                            let topMove = (imgRange.allRange.x[0] + imgRange.allRange.x[1])/2 - img.data.x;
                            img.data.x += topMove;
                            return;
                        }else{
                            let range = imgRange.imgRange[img.id];
                            let move = (imgRange.allRange.x[0] + imgRange.allRange.x[1])/2 - (range.x[0] + range.x[1]) / 2;
                            if(img.type == "path"){
                                img.data = movePath(img.data, move)
                                return;
                            }
                            if(img.type == "shapes"){
                                img.data.forEach((item,index)=>{
                                    img.data[index] = movePath(item,move);
                                });
                                return;
                            }
                            if(img.type == "texts"){
                                img.data.x += move;
                                return;
                            }
                        }
                    });

                    function movePath(data, move){
                        if(data.name == "ARC" || data.name == "LINE"){
                            data.st_x += move;
                            data.sp_x += move;
                            if(data.name == "ARC"){
                                data.o_x += move;
                            }
                        }else{
                            data.x += move;
                        }
                        return data;
                    }

                    return imgList;
                },
            }

            var strategy = alignStrategys[type];

            var recordHistory = this._update("align");

            if(this.figureData.selectData.length){
                // 将图形抽离出来
                // 获取需要对齐的数据
                // let pinIdList = [], imgIdList = []
                let imgIdList = this.figureData.selectData.map(img=>img.id);

                recordHistory.start(this.figureData.selectData);

                this.extractToPreview(imgIdList);

                let imgRange = {
                    pinRange:{},
                    imgRange:{},
                    allRange:null
                }

                this.figureData.selectData.forEach(img=>{
                    var range;
                    if(img.type == "pins"){
                        if(!imgRange.pinRange[img.pinid]){
                            let pad = this.imgRecord.pads.find(pad=>pad.id == img.padid);
                            range = measureUtil.computedPinRange({x:img.data.x,y:img.data.y},pad);
                            imgRange.pinRange[img.pinid] = range;
                        }
                    }else{
                        range = measureUtil.computedImageRange(img);
                        imgRange.imgRange[img.id] = range;
                    }
                    imgRange.allRange = measureUtil.compareRange(imgRange.allRange,range)
                });

                // this.figureData.selectData

                this.figureData.selectData = strategy(this.figureData.selectData,imgRange);
                
                Array(0).push.apply(this.figureData.imgDataTable,this.figureData.selectData);

                this.setPreview([]);

                this.drawPreview();

                this.figureData.selectData.forEach(img=>{
                    img.isPreview = false;
                });
                
                recordHistory.finish(this.figureData.selectData);

                this.layerDraw();

                // this.sendBoxChooseRange();
            }

        },

        // 替换数据中的图形
        replaceTableData(imgList){
            for(let i = 0; i < imgList.length; i++){
                let dataIndex = this.figureData.imgDataTable.findIndex((img)=>img.id == imgList[i].id);
                if(dataIndex!=-1){
                    this.figureData.imgDataTable[dataIndex] = util.copyObject(imgList[i]);
                }
            }
        }
    };

    // 插入图形用到的方法
    const insertEncaMethods = {
        // 开始插入
        initInsert(){
            this.resetStatus();

            this.status.insert = true;
            this.clearAllEvent();
            this.stopTouch();
        },

        // 插入图形
        insertImage(options,hook){
            this.initInsert();

            let strategyConfig = {
                units:this.imgConfig.units,
                layer:this.layer.boardLayer[0],
                ...options
            }

            if(options.type == "pin"){
                if(options.form == "SELF"){
                    strategyConfig.pad = this.imgRecord.pads.find(pad=>pad.id == options.padid);
                }
                strategyConfig.pins_id = this.imgRecord.pins_id;
                strategyConfig.pads_id = this.imgRecord.pads_id;
            }

            if(options.type == "copyBoxChooseImage"){
                strategyConfig.copyImages = util.copyObject(this.figureData.selectData);
                strategyConfig.range = this.getImageRange(this.figureData.selectData,this.imgRecord.pads);
                strategyConfig.pinLength = toOriginMathods.toOriginPins(strategyConfig.copyImages).length;
                strategyConfig.pins_id = this.imgRecord.pins_id;
                this.figureData.selectData = [];
                // this.sendBoxChooseRange();
                this.drawPreview();
            }
            
            let strategy = insertStrategy[options.type](strategyConfig);

            let clickEvent = (e)=>{
                let point = this.toPoint(this.getMousePointToCanvas(e));

                let result = strategy.clickEvent(point);
                
                hook && hook.add(util.copyObject(result));
            }

            let backout = (e)=>{
                strategy.backout();

                this.setPreview(strategy.getData());
            }

            let moveEvent = (e)=>{
                let point = this.toPoint(this.getMousePointToCanvas(e));
                let result = strategy.moveEvent(point);
                hook && hook.add && hook.add(result);
                this.setPreview(strategy.getData());
            };

            // 保存绘制
            let save = (saveType)=>{
                let insertData = strategy.save(saveType);

                let saveConfig = {
                    type:options.type,
                    insertData
                }

                if(saveConfig.type == "pin"){
                    saveConfig.form = options.form;
                }

                if(saveConfig.type == "copyBoxChooseImage"){
                    saveConfig.pinLength = strategyConfig.pinLength;
                }

                hook && hook.drawEnd && hook.drawEnd();

                this.insertExport = {};

                pauseDraw();

                this.saveInsertImage(saveConfig);
                if(this.status.pinCoord){
                    this.showPinCoord();
                }
            }
    
            // 开始绘制
            function startDraw(){
                Event.on("click",clickEvent);
                // self.canvasParent.oncontextmenu = backout;
                Event.on("mousemove",moveEvent);
                setTimeout(()=>{
                    Event.on("dblclick",save);
                },250);
            }

            // 停止绘制
            function pauseDraw(){
                Event.off("click",clickEvent);
                Event.off("mousemove",moveEvent);
                Event.off("dblclick",save);
            }

            startDraw();

            this.insertExport = {
                setEditData:(data)=>{
                    strategy.edit(data);
                    this.setPreview(strategy.getData());
                },
                backout,
                startDraw,
                pauseDraw,
                save
            }
        },

        // 清除所有编辑事件
        clearAllEvent(){
            this.setPreview([]);
        },

        // 保存所插入的图形
        saveInsertImage(saveConfig){
            let insertImage = [];
            if(saveConfig.type == "pin"){

                this.imgRecord.pins_id += saveConfig.insertData.pins.length;

                insertImage = handleUtil.handlerPinDraw(saveConfig.insertData.pins,saveConfig.insertData.pads);

                saveConfig.insertData.pins = insertImage;
            }else{
                // 增加pinid
                if(saveConfig.type == "copyBoxChooseImage"){
                    this.imgRecord.pins_id += toOriginMathods.toOriginPins(saveConfig.insertData).length;
                }
                insertImage = saveConfig.insertData;
            }

            if(insertImage && insertImage.length){
                
                insertImage.forEach(img=>{
                    delete img.isPreview;
                    img.id = ++this.imgRecord.countId;
                    this.figureData.imgDataTable.push(img);
                });
                if(saveConfig.type == "pin" && saveConfig.form !== "SELF"){
                    this.addPads(saveConfig.insertData.pads);
                }

                this._insert(saveConfig);
            }
            this.status.insert = false;
            this.clearAllEvent();
            this.startTouch();
            this.layerDraw();
        },

        // 清除无效pad
        _clearInvalidPad(){
            // 去除没被引用的pad
            let deletePads = [];
            let usePadId = {}
            this.figureData.imgDataTable.forEach(img=>{
                if(img.type == "pins"){
                    usePadId[img.padid] = true;
                }
            });
            for(let i = 0; i < this.imgRecord.pads.length; i++){
                let pad = this.imgRecord.pads[i];
                if(!usePadId[pad.id]){
                    deletePads.push(pad);
                    this.imgRecord.pads.splice(i--,1);
                }
            }
            return deletePads;
        },

        // 追加图形
        addImages(insertImage,addId){
            insertImage.forEach(img=>{
                if(img.isPreview){
                    delete img.isPreview;
                }
                if(addId || arguments.length == 1){
                    img.id = ++this.imgRecord.countId;
                }
                this.figureData.imgDataTable.push(img);
            });
            this.layerDraw();
        },

        // 追加新的pad
        addPads(pads){
            pads.forEach(pad=>{
                if(this.imgRecord.pads.findIndex(hasPad=>hasPad.id == pad.id) == -1){
                    this.imgRecord.pads.push(pad);
                    this.imgRecord.pads_id++;
                }
            });
            this._clearInvalidPad();
            Event.trigger("padUpdated",util.copyObject(this.imgRecord.pads));
        }
    }

    // 移动选中的图形
    /**
     * @this DrawEncapsulation
     */
    const moveSelectImage = {
        openMoveSelectImage(){
            // return;
            let startMove = false;

            var self = this;

            let point = {
                start:{
                    x: 0,
                    y: 0
                },
                end:{
                    x: 0,
                    y: 0
                }
            }


            // 移动的图形
            var movestartImages = [];
            // 备份编辑的数据
            var originEditData = {};
            // 编辑的数据
            var editData = {};

            // 鼠标按下事件
            let leftMousedown = (e)=>{
                if(e.button == 0){
                    point.start = this.getMousePointToCanvas(e);
                    let downPoint = this.toPoint(point.start,false);
                    let downImage = [];
                    if(this.status.edit){
                        editData = this.figureData.editData;
                        // 获取当前需要移动的图形
                        movestartImages = util.copyObject(this.figureData.previewData);
                        // 获取当前编辑的数据
                        originEditData = util.copyObject(this.figureData.editData);
                        
                        downImage = this.getImageToPoint(downPoint,this.figureData.previewData);
                        console.log(downImage);
                    }else{
                        downImage = this.getImageToPoint(downPoint,null,{oneFigure:true});
                        movestartImages = downImage;
                    }
                    if(downImage.length){
                        this.status.moveImage = true;
                        startMove = true;
                    }
                }
            }

            // 鼠标抬起事件
            let leftMouseup = (e)=>{
                if(e.button == 0){
                    startMove = false;
                    this.status.moveImage = false;
                    // this.figureData.editData = 
                }
            }
            // 移动事件
            let boxChooseMove = util.throttle((e)=>{
                if(!startMove){
                    return;
                }
                point.end = this.getMousePointToCanvas(e);
                let parsePoint = {
                    start:{},
                    end:{}
                }
                parsePoint.start = this.toPoint(point.start);
                parsePoint.end = this.toPoint(point.end);
                let offset = {
                    x: parsePoint.end.x - parsePoint.start.x,
                    y: parsePoint.end.y - parsePoint.start.y
                }
                if(this.status.edit){
                    this.figureData.previewData = handleUtil.moveImages(util.copyObject(movestartImages),offset);
                    moveImageTirgger(offset);
                }else{
                    let movedImages = handleUtil.moveImages(util.copyObject(movestartImages),offset);
                    this.replaceTableData(movedImages);
                    this.layerDraw();
                }
                this.drawPreview();
            },16);

            this.canvasParent.addEventListener("mousedown",leftMousedown);

            this.canvasParent.addEventListener("mouseup",leftMouseup);

            this.canvasParent.addEventListener("mousemove",boxChooseMove);

            this.closeMoveSelectImage = ()=>{
                this.status.boxChoose = false;

                this.canvasParent.removeEventListener("mousedown",leftMousedown);

                this.canvasParent.removeEventListener("mouseup",leftMouseup);

                this.canvasParent.removeEventListener("mousemove",boxChooseMove);
            }

            function moveImageTirgger(offset){
                moveEditImage(offset);
                Event.trigger("moveEditImage",self.figureData.editData);
            }

            function moveImage(offset){

            }

            function moveEditImage(offset){
                originEditData.pins.forEach((pin,index)=>{
                    editData.pins[index].x = pin.x + offset.x;
                    editData.pins[index].y = pin.y + offset.y;
                });
                originEditData.path.forEach((line,index)=>{
                    if(line.form == "ARC" || line.form == "LINE"){
                        editData.path[index].data.st_x = line.data.st_x + offset.x; 
                        editData.path[index].data.st_y = line.data.st_y + offset.y; 
                        editData.path[index].data.sp_x = line.data.sp_x + offset.x; 
                        editData.path[index].data.sp_y = line.data.sp_y + offset.y;
                        if(line.form == "ARC"){
                            editData.path[index].data.o_x = line.data.o_x + offset.x; 
                            editData.path[index].data.o_y = line.data.o_y + offset.y;
                        }
                    }
                    if(line.form == "S" || line.form == "OC" || line.form == "OV"){
                        editData.path[index].data.x = line.data.x + offset.x;
                        editData.path[index].data.y = line.data.y + offset.y;
                    }
                });
                originEditData.texts.forEach((text,index)=>{
                    editData.texts[index].data.x = text.data.x + offset.x;
                    editData.texts[index].data.y = text.data.y + offset.y;
                });
            }
        },

        closeMoveSelectImage(){}
    }

    // 测量用到的方法
    const measureMethods = {
        // 开始测量
        startMeasure(){
            this.resetStatus();
            // 开始测量
            this.startTouch();
            this.status.measure = true;
            this.canvasParent.onclick = ()=>{
                let measureData = this.figureData.measureData;
                let selectImages = util.copyObject(this.figureData.previewData) || [];
                if(selectImages.length){
                    let selectImage = selectImages[selectImages.length-1];
                    if(!measureData.start || isEmpty(measureData.start) || !isEmpty(measureData.end)){
                        measureData.startImages = selectImages;
                        measureData.endImages = [];
                    }else{
                        measureData.endImages = selectImages;
                    }
                    this._setMeasureData(selectImage);
                }else{
                    this.clearMeasure();
                }
            }
        },

        // 结束测量
        cancelMeasure(){
            this.status.measure = false;
            this.canvasParent.onclick = null;
            this.clearMeasure();
        },

        // 设置测量数据
        _setMeasureData(imgData){
            let self = this;
            let measureData = this.figureData.measureData;
            if(!measureData.start || isEmpty(measureData.start) || !isEmpty(measureData.end)){
                measureData.start = handlerMeasureData(imgData);
                measureData.end = {};
                measureData.dist = 0;
            }else{
                measureData.end = handlerMeasureData(imgData);
                let dist = Math.sqrt((measureData.start.x - measureData.end.x) ** 2 + (measureData.start.y - measureData.end.y) ** 2);
                measureData.w = parseFloat(Math.abs(measureData.start.x - measureData.end.x).toFixed(2));
                measureData.h = parseFloat(Math.abs(measureData.start.y - measureData.end.y).toFixed(2));
                measureData.dist = parseFloat(dist.toFixed((2)));
            }

            this.drawMeasure();

            function handlerMeasureData(data){
                let handlerData;
                // 将imgdata数据进行转换
                if(data.type === "pins"){
                    // 获取pad
                    let pad = self.imgRecord.pads.find(pad=>pad.id === data.padid);
                    if(!pad){
                        alert("出错了：pad获取失败");
                        return;
                    }
                    let padSize = {};
                    if(!isEmpty(pad.t)){
                        padSize = measureUtil.computedPadSize({t:pad.t,drill:pad.drill});
                    }else if(!isEmpty(pad.b)){
                        padSize = measureUtil.computedPadSize({b:pad.b,drill:pad.drill});
                    }else{
                        padSize = measureUtil.computedPadSize({drill:pad.drill});
                    }
                    handlerData = {
                        x:data.data.x,
                        y:data.data.y,
                        type:data.type,
                        ...padSize
                    }
                }else if(data.type === "path"){
                    if(data.form === "S" || data.form === "OV" || data.form === "OC"){
                        handlerData = {
                            x:data.data.x,
                            type:data.type,
                            y:data.data.y
                        }
                    }else{
                        handlerData = {
                            x:(data.data.st_x + data.data.sp_x) / 2,
                            type:data.type,
                            y:(data.data.st_y + data.data.sp_y) / 2,
                        }
                    }
                }else if(data.type === "texts"){
                    handlerData = {
                        x:data.data.x,
                        y:data.data.y,
                        type:data.type
                    }
                }else if(data.type === "shapes"){
                    handlerData = measureUtil.computedShapeRange(data);
                    handlerData.type = "shapes";
                }
                return handlerData;
            }
        },

        // 绘制测量
        drawMeasure(){
            if(!this.status.measure){
                return;
            }
            let units = this.imgConfig.units;
            let scale = units === "mm" ? this.scale * 39.37 : this.scale;
            let drawMeasureData = {
                dist:this.figureData.measureData.dist,
                start:handleMeasureData(this.figureData.measureData.start,scale),
                end:handleMeasureData(this.figureData.measureData.end,scale),
                units,
                w:this.figureData.measureData.w,
                h:this.figureData.measureData.h
            }
            this.drawObj.drawTop.clear();
            this.drawObj.drawTop.setMeasure(drawMeasureData);
            
            // 处理图形数据
            function handleMeasureData(endPointData,scale){
                let handlerData = util.copyObject(endPointData);
                if(!handlerData || isEmpty(handlerData)){
                    return {};
                }
                handlerData.x = handlerData.x * scale;
                handlerData.y = - handlerData.y * scale;
                if(handlerData.type === "pins"){
                    handlerData.scaleW = handlerData.w * scale;
                    handlerData.scaleH = handlerData.h * scale;
                    handlerData.drill?.forEach?.(size=>{
                        size.scaleW = size.w * scale;
                        size.scaleH = size.h * scale;
                    });
                }
                return handlerData;
            }
        },

        // 清空绘制
        clearMeasure(){
            
            this.figureData.measureData = {
                startImages:[],
                endImages:[],
                start:{},
                end:{},
                dist:0
            };
            this.drawObj.drawTop.clear();
        }
    }

    // 坐标类方法
    const coordsMethods = {
        // 将鼠标位置进行偏移转换
        transformMousePoint(e){
            return this.toCanvasOffsetPoint(this.toPoint(this.getMousePointToCanvas(e)));
        },

        // 将坐标位置转换为相对于canvasParent的位置
        toCanvasOffsetPoint(point){
            return {
                x:this.toReallyNumber(point.x,"x"),
                y:this.toReallyNumber(point.y,"y")
            }
        },

        // 转换坐标
        /**
         * @param {{}} point  需要转换的x，y轴，位于canvas左上角的位置
         * @param {?boolean} revise  是否需要矫正坐标，默认为true
         * @returns 
         */
        toPoint(point,revise){
            let scale = this.imgConfig.units ==="mm"?this.scale * 39.37 : this.scale;
            if(typeof revise === "undefined"){
                revise = true;
            }
            let origin = {
                x:this.origin.x,
                y:this.origin.y
            }
            if(this.imgConfig.mirror){
                origin.x = this.canvasSize[0] -  origin.x;
            }
            let rePoint = {
                x:(point.x - origin.x) / scale * (this.imgConfig.mirror ? -1 : 1),
                y: - (point.y - origin.y) / scale 
            }
            if(revise){
                return util.revisePoint(rePoint,this.editConfig.smallDist);
            }else{
                return rePoint;
            }
        },

        // 获取鼠标相对于canvasParent的位置
        getMousePoint(e){
            var rect = this.canvasParent.getBoundingClientRect();

            return {
                x: e.clientX - rect.left,
                y: e.clientY - rect.top
            }
        },

        // 
        getMousePointToCanvas(e){
            
            let rotatePoint = this.getMousePoint(e);

            if(!this.imgConfig.rotate){
                return rotatePoint;
            }

            let center = [
                this.canvasSize[0] / 2,
                this.canvasSize[1] / 2
            ]

            let boxPoints = [
                [0,0],
                [0, this.canvasSize[0]],
                [this.canvasSize[0], this.canvasSize[1]],
                [this.canvasSize[1], 0]
            ];

            let rotatePoints = util.rotatePoints(boxPoints,center,this.imgConfig.rotate);

            let rotateBoxRange = {
                x:[Math.min(...rotatePoints.map(p=>p[0])),Math.max(...rotatePoints.map(p=>p[0]))],
                y:[Math.min(...rotatePoints.map(p=>p[0])),Math.max(...rotatePoints.map(p=>p[0]))]
            }

            let rotateBoxSize = [rotateBoxRange.x[1] - rotateBoxRange.x[0],rotateBoxRange.y[1] - rotateBoxRange.y[0]];

            let rotateBoxCenter = [rotateBoxSize[0] / 2, rotateBoxSize[1] / 2];

            let rotateSpace = [rotatePoint[0] - rotateBoxCenter[0],rotatePoint[1] - rotateBoxCenter[1]];

            let restPoint = [rotateSpace[0] + center[0], rotateSpace[1] + center[1]]

            
            let point = util.rotatePoint(restPoint,center,-45);

            return {
                x: point[0],
                y: point[1]
            };
        }
    }

    // 删除
    const deleteMethods = {
        deleteImage(type,id){
            let deleteStrategy = {
                pin(imgList,id){
                    var deleteImages = [];
                    imgList = imgList.filter(img=>{
                        if(img.type === "pins" && img.pinid == id){
                            deleteImages.push(img);
                            return false;
                        }
                        return true;
                    });
                    return {deleteImages,imgList};
                },
                image(imgList,id){
                    var deleteImages = [];
                    imgList = imgList.filter(img=>{
                        if(img.type !== "pins" && img.id == id){
                            deleteImages.push(img);
                            return false;
                        }
                        return true;
                    });
                    return {deleteImages,imgList};
                }
            }

            let delStrategy = deleteStrategy[type];

            let {deleteImages,imgList} = delStrategy(this.figureData.imgDataTable,id);
            
            this.figureData.imgDataTable = imgList;

            var deleteInfo = {
                deleteImages
            }

            // 删除演示层
            this.figureData.previewData = delStrategy(this.figureData.previewData,id).imgList;

            if(type == "pin"){
                deleteInfo.deletePads = this._clearInvalidPad();
                Event.trigger("padUpdated",util.copyObject(this.imgRecord.pads));
            }

            this._delete(type,deleteInfo);

            this.drawPreview();
            this.layerDraw();
        },

        // 删除所有选中的图形
        deleteSelectImages(){
            let selectData = util.copyObject(this.figureData.selectData) || [];
            
            this._deleteImgTableImage((img)=>{
                let selectIndex = selectData.findIndex(selectImg=>selectImg.id == img.id)
                if(~selectIndex){
                    selectData.splice(selectIndex,1);
                    return true;
                }
                return false;
            });

            var deleteInfo = {
                deleteImages:this.figureData.selectData
            }

            deleteInfo.deletePads = this._clearInvalidPad();
            if(deleteInfo.deletePads.length){
                Event.trigger("padUpdated",util.copyObject(this.imgRecord.pads));
            }

            this._delete("select",deleteInfo);

            this.figureData.selectData = [];

            this.setPreview([]);

            this.drawPreview();

            this.layerDraw();

            // this.sendBoxChooseRange();

        }
    }

    // 基础工具类方法
    const baseUtilMethods = {
        resetStatus(){
            if(this.status.edit){
                this.saveEdit();
            }
            if(this.status.measure){
                this.cancelMeasure();
            }
            if(this.status.resetOrigin){
                this.finishSetOrigin();
            }
            if(this.status.insert){
                this.insertExport.save("once");
            }
            Event.trigger("errorExecute");
        },

        // 转换为原始数据
        toOrigin(){
            let imgData = toOriginMathods.transformOriginData(util.copyObject(this.figureData.imgDataTable),util.copyObject(this.imgRecord.pads));
            let encaData = util.copyObject(this.encaData);
            imgData.header.units = this.imgConfig.units;
            encaData.img_data = imgData;
            encaData.units = this.imgConfig.units;
            return encaData;
        },

        // 切换单位制
        changeUnits(units){

            if((units !== "mm" && units !== "mils") || this.imgConfig.units == units){
                return;
            }
            
            this.resetStatus();

            let scale = units === "mm" ? 0.0254 : 1 / 0.0254;

            let padLayers = ["b","bs_t","bs_b","bp_t","bp_b","t","ts_t","ts_b","tp_t","tp_b","i","is_t","is_b","ip_t","ip_b","drill"];

            this.imgRecord.pads.forEach(pad=>{
                padLayers.forEach(layer=>{
                    if(layer == "drill"){
                        pad[layer].forEach((drill,index)=>{
                            pad[layer][index] = changeData(drill,scale);
                        });
                    }
                    if(pad[layer] && pad[layer].form){
                        pad[layer] = changeData(pad[layer],scale);
                    }
                });
            });

            this.figureData.imgDataTable.forEach(img=>{
                if(img.type == "shapes"){
                    img.data.forEach((line,index)=>{
                        img.data[index] = changeData(line,scale);
                    });
                }else{
                    img.data = changeData(img.data,scale);
                }
            });

            this.imgConfig.units = units;
            this.imgConfig.gridSize.x = units=="mm"?0.5:39.37;
            this.imgConfig.gridSize.y = units == "mm"?0.5:39.37;
            this.editConfig.smallDist.x = units=="mm"?0.5:39.37;
            this.editConfig.smallDist.y = units=="mm"?0.5:39.37;

            if(this.status.pinCoord){
                this.showPinCoord();
            }

            this.layerDraw();

            function changeData(data,scale){
                let attrs = ["o_x","o_y","x","y","st_x","st_y","sp_x","sp_y","width","w","h","r","path","skewing_x","skewing_y","textblock","textheight","textwidth"];
                attrs.forEach(attr=>{
                    if(data[attr]){
                        if(attr == "path"){
                            if(data.path instanceof Array){
                                data.path.forEach((line,index)=>{
                                    data.path[index] = changeData(line,scale);
                                });
                            }else{
                                data.path = changeData(data.path,scale);
                            }
                        }else{
                            data[attr] = parseFloat((data[attr] * scale).toFixed(4));
                        }
                    }
                });
                return data;
            }
        },

        // 检查标志顺序位
        showFlagOrderBit(){
            this.drawObj.drawFlag.clear();

            this.status.flag = true;

            let scale = this.imgConfig.units == "mm"?this.scale*39.37:this.scale;

            // 获取所有的pin
            let pins = this.figureData.imgDataTable.filter(img=>img.type == "pins");
            pins = toOriginMathods.toOriginPins(pins);
            let detections = [/^\d+$/, /^[a-zA-Z]+$/, /^[a-zA-Z]+\d+$/];
            let pinsFilter = [
                [],
                [],
                []
            ]
            pins.forEach(pin=>{
                for(let i = 0; i < detections.length; i++){
                    if(detections[i].test(pin.pin_num)){
                        pinsFilter[i].push({
                            num:pin.pin_num,
                            coordinates:[pin.x * scale, - pin.y * scale,pin.pin_num]
                        })
                        break;
                    }
                }
            });
            pinsFilter[0] = pinsFilter[0].sort((a, b) => a.num - b.num).map(pin=>pin.coordinates);

            pinsFilter[1] = pinsFilter[1].sort((a, b) => a.num > b.num ? 1 : -1).map(pin=>pin.coordinates);

            var numberReg = /\d+/gi, strReg = /[a-zA-Z]+/gi;

            pinsFilter[2] = pinsFilter[2].sort((a, b)=>{
                let aLeft = a.num.match(strReg)[0];
                let bLeft = b.num.match(strReg)[0];
                let aRight = a.num.match(numberReg)[0];
                let bRight = b.num.match(numberReg)[0];
                // console.log(aLeft,bLeft)
                if(aLeft != bLeft){
                    if(aLeft.length === bLeft.length){
                        return aLeft > bLeft ? 1 : -1;
                    }else{
                        return aLeft.length - bLeft.length;
                    }
                }else{
                    return aRight - bRight;
                }
            }).map(pin=>pin.coordinates);
            this.drawObj.drawFlag.drawExamine(pinsFilter);
        },

        // 隐藏标志顺序位
        hiddenFlagOrderBit(){
            this.drawObj.drawFlag.clear();

            this.status.flag = false;
        },

        // 将原始数值转换为真实数值
        toReallyNumber(originNum,type){
            let scale = this.imgConfig.units ==="mm"?this.scale * 39.37 : this.scale;
            return type == "x" ? originNum * scale + this.origin.x : - originNum * scale + this.origin.y
        },

        // 引脚排序
        startPinSort(firstNum){

            let self = this;

            this.stopTouch();

            let selectPinIds = [];

            let selectPins = [];

            // 编号与pinid对应集合
            let pinidToNum = {};

            // 编号集合
            let numList = [];

            // 传入的编号字符类型
            let numType = generatePinNumber.textType(firstNum);

            // 前一个编号
            let beforeNum = "";

            // 是否需要换行
            let isBreak = false;

            var mouseMove = (e)=>{
                if(!e.ctrlKey){
                     return;
                }
                let mousePoint = this.getMousePoint(e);
                let point = this.toPoint(mousePoint);
                let mouseDownImage = this.getImageToPoint(point,null,{onePin:true});

                if(mouseDownImage.length){
                    let pinid = mouseDownImage[0].pinid;
                    if(!pinidToNum[pinid]){
                        selectPinIds.push(pinid);
                        
                        let pin_num = "";
                        if(selectPinIds.length == 1){
                            pin_num = firstNum;
                        }else{
                            pin_num = generatePinNumber.textAdd(beforeNum,numType,isBreak);
                            isBreak = false;
                        }

                        beforeNum = pin_num;

                        pinidToNum[pinid] = pin_num;

                        numList.push(pin_num);

                        mouseDownImage.forEach(img=>{
                            img.pin_num = pin_num;
                        });

                        selectPins.push(...mouseDownImage);
                    }
                }
                updatePinSortPreview();
            }

            Event.on("mousemove",mouseMove,"setPinSortMouseMove");

            Event.on("click",()=>{
                isBreak = true;
            },"pinNumBreak");

            Event.on("dblclick",()=>{
                this.figureData.imgDataTable.forEach(img=>{
                    if(img.type == "pins" && pinidToNum[img.pinid]){
                        img.pin_num = pinidToNum[img.pinid];
                    }
                });
                this.layerDraw();

                this.setPreview([]);

                this.stopPinSort();

                this.startTouch();

            },"pinSortFinish");

            // 撤回
            Event.on("contextmenu",()=>{
                let backoutPinId = selectPinIds.pop();

                numList.pop();

                beforeNum = numList[numList.length - 1];

                isBreak = false;

                pinidToNum[backoutPinId] = null;
                for(let i = selectPins.length - 1; i >= 0; i--){
                    if(selectPins[i].pinid == backoutPinId){
                        selectPins.pop();
                    }else{
                        break;
                    }
                }
                
                updatePinSortPreview();

            },"pinSortBackout");


            function updatePinSortPreview(){
                let previewImage = util.copyObject(selectPins);

                previewImage.forEach(img=>{
                    img.isPreview = true;
                });

                self.setPreview(previewImage);
            }

        },

        // 停止引脚排序
        stopPinSort(){
            Event.aliasOff("mousemove","setPinSortMouseMove");
            Event.aliasOff("click","pinNumBreak");
            Event.aliasOff("dblclick","pinSortFinish");
            Event.aliasOff("contextmenu","pinSortBackout");
            this.startTouch();
        },
    }

    // 显示引脚信息
    const showPinCoordMethods = {
        // 显示引脚坐标
        showPinCoord(){
            this.status.pinCoord = true;
            // 获取所有pin
            let pins = toOriginMathods.toOriginPins(this.figureData.imgDataTable);
            console.log(pins);

            let xGroupPins = {},yGroupPins = {}, xList = [], yList = [];
            pins.forEach(pin=>{
                if(!xGroupPins[pin.x]){
                    xList.push(pin.x);
                    xGroupPins[pin.x] = [];
                }
                if(!yGroupPins[pin.y]){
                    yList.push(pin.y);
                    yGroupPins[pin.y] = [];
                }
                xGroupPins[pin.x].push(pin);
                yGroupPins[pin.y].push(pin);
            });

            xList.sort((a,b)=>a - b);
            yList.sort((a,b)=>a - b);

            let xGroups = [],yGroups = [];

            let minSpace = (xList[1] - xList[0]) || (yList[1] - yList[0]) || (this.imgConfig.units == "mm" ? 0.5 : 18);
            xList.forEach((x,index)=>{
                if(xList[index + 1]){
                    let space = xList[index + 1] - x;
                    if(minSpace > space){
                        minSpace = space;
                    }
                }
                xGroupPins[x].sort((a,b)=>a.y - b.y);
                xGroups.push({
                    value: x,
                    pins:xGroupPins[x]
                });
            });

            yList.forEach((y,index)=>{
                if(yList[index + 1]){
                    let space = yList[index + 1] - y;
                    if(minSpace > space){
                        minSpace = space;
                    }
                }
                yGroupPins[y].sort((a,b)=>a.x - b.x);
                yGroups.push({
                    value: y,
                    pins:yGroupPins[y]
                });
            });

            console.log(yList);

            minSpace -= minSpace / 4;

            let maxnum = generateFigure.createText({
                textblock: minSpace,
                content: "12345.67899900"
            },this.drawObj.drawPreview).data.textwidth;

            let textSize = minSpace;

            let imgList = [];

            let lineWeight = this.imgConfig.units == "mm" ? 0.02 : 1;

            xGroups.forEach((xGroup,i)=>{
                let mark = xGroup.value.toString();
                let pins = xGroup.pins.map(pin=>pin.pinid);
                let numMark = pins.length.toString();

                let line = {
                    type:"path",
                    form:"LINE",
                    layer:"pinCoord",
                    pins,
                    data:{
                        name:"LINE",
                        st_x: xGroup.value,
                        sp_x: xGroup.value,
                        width: lineWeight,
                        st_y: yGroups[yGroups.length - 1].value,
                        sp_y: yGroups[0].value - maxnum
                    }
                }

                let numText = generateFigure.createText({
                    layer:"pinCoordCount",
                    content:numMark,
                    textblock: minSpace,
                    x: xGroup.value,
                    y: line.data.sp_y,
                    fontWeight: 100,
                    rotate: 270,
                    strokeRect: "#569CD6"
                },this.drawObj.drawPreview);

                numText.pins = pins;

                numText.data.y -= numText.data.textwidth / 2;

                let text = generateFigure.createText({
                    layer:"pinCoord",
                    content:mark,
                    textblock: minSpace,
                    x: xGroup.value,
                    y: line.data.sp_y - numText.data.textwidth - minSpace,
                    fontWeight: 100,
                    rotate: 270
                },this.drawObj.drawPreview);

                text.bindFigure = line;
                line.bindFigure = text;

                text.data.y -= text.data.textwidth / 2;

                text.pins = pins;

                if(xGroups[i - 1]){
                    let nextX = xGroups[i - 1].value;
                    let nextPins = xGroups[i - 1].pins.map(pin=>pin.pinid);
                    let rowSpacing = Number((xGroup.value - nextX).toFixed(6));

                    let centerText = generateFigure.createText({
                        layer:"spacePinCoord",
                        content: rowSpacing,
                        textblock: minSpace,
                        x: xGroup.value - rowSpacing / 2,
                        y: line.data.sp_y + maxnum / 2,
                        fontWeight: 100,
                        rotate: 270,
                    },this.drawObj.drawPreview);

                    centerText.pins = pins.concat(nextPins);

                    imgList.push(centerText);
                }
                
                imgList.push(line,text,numText);
            })

            yGroups.forEach((yGroup,index)=>{
                let mark = yGroup.value.toString();
                let pins = yGroup.pins.map(pin=>pin.pinid);
                let numMark = pins.length.toString();

                let line = {
                    type:"path",
                    form:"LINE",
                    layer:"pinCoord",
                    pins,
                    data:{
                        name:"LINE",
                        st_x: xGroups[xGroups.length - 1].value,
                        sp_x: xGroups[0].value - maxnum,
                        width:lineWeight,
                        st_y: yGroup.value,
                        sp_y: yGroup.value
                    }
                };

                let numText = generateFigure.createText({
                    layer:"pinCoordCount",
                    content:numMark,
                    textblock: minSpace,
                    x: line.data.sp_x,
                    y: yGroup.value,
                    fontWeight: 100,
                    strokeRect: "#569CD6"
                },this.drawObj.drawPreview);

                numText.pins = pins;

                numText.data.x -= numText.data.textwidth / 2;

                let text = generateFigure.createText({
                    layer:"pinCoord",
                    content:mark,
                    textblock: minSpace,
                    x: line.data.sp_x - numText.data.textwidth - minSpace,
                    y: yGroup.value,
                    fontWeight: 100,
                },this.drawObj.drawPreview);

                text.data.x -= text.data.textwidth / 2;

                text.pins = pins;
                
                text.bindFigure = line;
                line.bindFigure = text;

                imgList.push(line,text,numText);

                if(yGroups[index + 1]){
                    let nextY = yGroups[index + 1].value;
                    let nextPins = yGroups[index + 1].pins.map(pin=>pin.pinid);
                    let rowSpacing = Number((nextY - yGroup.value).toFixed(6));

                    let cMark = rowSpacing;

                    let centerText = generateFigure.createText({
                        layer:"spacePinCoord",
                        content: cMark,
                        textblock: minSpace,
                        x: line.data.sp_x + maxnum / 2,
                        y: yGroup.value + rowSpacing / 2,
                        fontWeight: 100,
                    },this.drawObj.drawPreview);

                    centerText.pins = pins.concat(nextPins);

                    imgList.push(centerText);
                }
            });

            this.temporaryData.pinCoordInfo = {
                xGroups,yGroups,imgList
            }

            this.drawPreview();
        },

        // 关闭引脚显示
        hidePinCoord(){
            this.status.pinCoord = false;
            this.drawPreview();
        }
    }

    // 镜像复制
    const mirrorCopy = {
        startMirrorCopy(type){
            if(this.status.mirrorCopy){
                this.cancelMirrorCopy(true);
            }

            this.status.mirrorCopy = true;

            let selectData = util.copyObject(this.figureData.selectData);

            // 提取pin
            let pins = toOriginMathods.toOriginPins(selectData);

            let pinidCount = this.imgRecord.pins_id;

            // 提取pad
            let padIds = [...new Set(pins.map(pin=>pin.padid))];

            let pads = util.copyObject(this.imgRecord.pads.filter(pad=>padIds.indexOf(pad.id) !== -1));

            // 更新padid
            let old2New = {},padIdcount = this.imgRecord.pads_id;
            pads.forEach(pad=>{
                old2New[pad.id] = ++padIdcount;
                pad.id = padIdcount;
            });
            console.log(old2New,pins);
            // 增加pinid
            pins.forEach(pin=>{
                pin.pinid = ++pinidCount;
                pin.padid = old2New[pin.padid];
            });

            // 提取其他图形
            let otherImages = selectData.filter(img=>img.type !== "pins");
            
            let copyData = [];

            let mPads = mirrorPads(pads,type);

            Event.on("errorExecute",()=>{
                this.cancelMirrorCopy();
            },"mirrorErrorExecute");

            Event.on("setMirrorMarkPoint",(markPoint)=>{
                let mOtherImages = util.copyObject(otherImages);
                
                let mPins = util.copyObject(pins);

                copyData = mirrorData(mOtherImages,mPins,mPads,markPoint,type);

                this.temporaryData.mirrorCopyData = copyData;

                this.drawPreview();

            },"setMirrorMarkPoint");

            Event.on("dblclick",()=>{

                this.imgRecord.pins_id += pins.length;

                this.addImages(copyData);

                this.addPads(mPads);

                this.cancelMirrorCopy();
            },"saveMirrorCopy");

            function mirrorData(mOtherImages,mPins,mirrorPads,markPoint,type){
                let mirrorOtherImage = mOtherImages.map(img=>{
                    if(img.data.rotate){
                        if(type == "horizontal" || type == "vertical"){
                            img.data.rotate = 360 - img.data.rotate;
                        }else{
                            img.data.rotate = 180 - img.data.rotate;
                        }
                    }
                    if(img.type == "path"){
                        if(img.form == "S" || img.form == "OV" || img.form == "OC"){
                            if(type == "horizontal" || type == "hor_ver"){
                                img.data.x = 2 * markPoint.x - img.data.x;
                            }
                            if(type == "vertical" || type == "hor_ver"){
                                img.data.y = 2 * markPoint.y - img.data.y;
                            }
                        }else{
                            img.data = mirrorLine(img.data,markPoint,type);
                        }
                        return img;
                    }
                    if(img.type == "texts"){
                        if(type == "horizontal" || type == "hor_ver"){
                            img.data.x = 2 * markPoint.x - img.data.x;
                        }
                        if(type == "vertical" || type == "hor_ver"){
                            img.data.y = 2 * markPoint.y - img.data.y;
                        }
                        return img;
                    }
                    if(img.type == "shapes"){
                        img.data = img.data.map(line=>{
                            return  mirrorLine(line,markPoint,type);
                        });
                        return img;
                    }
                });

                let mirrorPins = mPins.map(pin=>{
                    if(pin.rotate){
                        if(type == "horizontal" || type == "vertical"){
                            pin.rotate = 360 - pin.rotate;
                        }else{
                            pin.rotate = 180 - pin.rotate;
                        }
                    }
                    if(type == "horizontal" || type == "hor_ver"){
                        pin.x = 2 * markPoint.x - pin.x;
                    }
                    if(type == "vertical" || type == "hor_ver"){
                        pin.y = 2 * markPoint.y - pin.y;
                    }
                    return pin;
                });

                return [...mirrorOtherImage,...handleUtil.handlerPinDraw(mirrorPins,mirrorPads)];


                function mirrorLine(lineData,markPoint,type){
                    let form = lineData.name.toUpperCase();
                    if(form == "ARC"){
                        if(type == "horizontal" || type == "vertical"){
                            lineData.arc_r = lineData.arc_r == "nil" ? "t" : "nil";
                        }
                    }
                    if(type == "horizontal" || type == "hor_ver"){
                        lineData.st_x = 2 * markPoint.x - lineData.st_x;
                        lineData.sp_x = 2 * markPoint.x - lineData.sp_x;
                        if(form == "ARC"){
                            lineData.o_x = 2 * markPoint.x - lineData.o_x;
                        }
                    }
                    if(type == "vertical" || type == "hor_ver"){
                        lineData.st_y = 2 * markPoint.y - lineData.st_y;
                        lineData.sp_y = 2 * markPoint.y - lineData.sp_y;
                        if(form == "ARC"){
                            lineData.o_y = 2 * markPoint.y - lineData.o_y;
                        }
                    }
                    return lineData;
                }
            }

            function mirrorPads(mPads,type){
                let mirrorPads = mPads.map(pad=>{
                    let padSmallLayer = ["b","bs_t","bs_b","bp_t","bp_b","t","ts_t","ts_b","tp_t","tp_b","i","is_t","is_b","ip_t","ip_b","drill"];

                    padSmallLayer.forEach(layer=>{
                        if(layer=="drill"){
                            pad[layer] = pad[layer].map(drill=>mirrorPadLayer(drill,type));
                        }else{
                            if(pad[layer]){
                                pad[layer] = mirrorPadLayer(pad[layer],type);
                            }
                        }
                    });
                    return pad;
                });

                function mirrorPadLayer(padLayerData,type){
                    if(padLayerData.form){
                        if(type == "horizontal" || type == "hor_ver"){
                            padLayerData.skewing_x *= -1;
                        }
                        if(type == "vertical" || type == "hor_ver"){
                            padLayerData.skewing_y *= -1;
                        }
                        if(padLayerData.form == "PATH"){
                            padLayerData.path.forEach(line=>{
                                let form = line.name.toUpperCase();
                                if(form == "ARC"){
                                    if(type == "horizontal" || type == "vertical"){
                                        line.arc_r = line.arc_r == "nil" ? "t" : "nil";
                                    }
                                }
                                if(type == "horizontal" || type == "hor_ver"){
                                    line.st_x *= -1;
                                    line.sp_x *= -1;
                                    if(form == "ARC"){
                                        line.o_x *= -1;
                                    }
                                }
                                if(type == "vertical" || type == "hor_ver"){
                                    line.st_y *= -1;
                                    line.sp_y *= -1;
                                    if(form == "ARC"){
                                        line.o_y *= -1;
                                    }
                                }
                            });
                        }
                    }
                    return padLayerData;
                }
                return mirrorPads;
            }
        },

        cancelMirrorCopy(notTrigger){
            this.temporaryData.mirrorCopyData = [];
            this.status.mirrorCopy = false;
            this.drawPreview();
            Event.aliasOff("setMirrorMarkPoint","setMirrorMarkPoint");
            Event.aliasOff("dblclick","saveMirrorCopy");
            Event.aliasOff("errorExecute","mirrorErrorExecute");
            if(!notTrigger){
                Event.trigger("cancelMirrorCopy");
            }
        }
    }

    Object.assign(DrawEncapsulation.prototype,drawEncaMethods,displayControl,editEncaMethods,insertEncaMethods,deleteMethods,selectMethods,measureMethods,baseUtilMethods,moveSelectImage,historyMethods,boxChooseMethods,coordsMethods,mirrorCopy,showPinCoordMethods);

    // DrawEncapsulation.prototype = {...drawEncaMethods,...editEncaMethods,...insertEncaMethods,...deleteMethods,...selectMethods,...measureMethods,...baseUtilMethods};

    DrawEncapsulation.util = util;

    DrawEncapsulation.event = Event;

    // Object.setPrototypeOf(DrawEncapsulation,null);
    // Object.setPrototypeOf(DrawEncapsulation,drawEncaMethods);

    // 原始数据转换为绘图数据
    function transformOriginalData(){

    }

    return DrawEncapsulation;
})();


// I O Q S X Z